hyperspace-sdk-ts 3.1.1 → 3.1.2

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/dist/client.js CHANGED
@@ -224,7 +224,77 @@ class HyperspaceClient {
224
224
  });
225
225
  return out;
226
226
  }
227
+ toProtoFilter(f) {
228
+ const pf = new hyperspace_pb.Filter();
229
+ if (f.match) {
230
+ const m = new hyperspace_pb.Match();
231
+ m.setKey(f.match.key);
232
+ m.setValue(f.match.value);
233
+ pf.setMatch(m);
234
+ }
235
+ else if (f.prefix) {
236
+ const p = new hyperspace_pb.Prefix();
237
+ p.setKey(f.prefix.key);
238
+ p.setPrefix(f.prefix.prefix);
239
+ pf.setPrefix(p);
240
+ }
241
+ else if (f.range) {
242
+ const r = new hyperspace_pb.Range();
243
+ r.setKey(f.range.key);
244
+ if (f.range.gte !== undefined) {
245
+ if (Number.isInteger(f.range.gte))
246
+ r.setGte(f.range.gte);
247
+ else
248
+ r.setGteF64(f.range.gte);
249
+ }
250
+ if (f.range.lte !== undefined) {
251
+ if (Number.isInteger(f.range.lte))
252
+ r.setLte(f.range.lte);
253
+ else
254
+ r.setLteF64(f.range.lte);
255
+ }
256
+ pf.setRange(r);
257
+ }
258
+ else if (f.inCone) {
259
+ const c = new hyperspace_pb.InCone();
260
+ c.setAxesList(f.inCone.axes);
261
+ c.setAperturesList(f.inCone.apertures);
262
+ c.setCen(f.inCone.cen[0] || 0);
263
+ pf.setInCone(c);
264
+ }
265
+ else if (f.inBall) {
266
+ const b = new hyperspace_pb.InBall();
267
+ b.setCenterList(f.inBall.center);
268
+ b.setRadius(f.inBall.radius);
269
+ pf.setInBall(b);
270
+ }
271
+ else if (f.inBox) {
272
+ const b = new hyperspace_pb.InBox();
273
+ b.setMinBoundsList(f.inBox.minBounds);
274
+ b.setMaxBoundsList(f.inBox.maxBounds);
275
+ pf.setInBox(b);
276
+ }
277
+ else if (f.and) {
278
+ const andOp = new hyperspace_pb.FilterAnd();
279
+ andOp.setConditionsList(f.and.map(cond => this.toProtoFilter(cond)));
280
+ pf.setAndOp(andOp);
281
+ }
282
+ else if (f.or) {
283
+ const orOp = new hyperspace_pb.FilterOr();
284
+ orOp.setConditionsList(f.or.map(cond => this.toProtoFilter(cond)));
285
+ pf.setOrOp(orOp);
286
+ }
287
+ else if (f.not) {
288
+ const notOp = new hyperspace_pb.FilterNot();
289
+ notOp.setCondition(this.toProtoFilter(f.not));
290
+ pf.setNotOp(notOp);
291
+ }
292
+ return pf;
293
+ }
227
294
  constructor(host = 'localhost:50051', apiKey, userId) {
295
+ this.host = host;
296
+ this.apiKey = apiKey;
297
+ this.userId = userId;
228
298
  const options = {
229
299
  'grpc.max_send_message_length': 64 * 1024 * 1024,
230
300
  'grpc.max_receive_message_length': 64 * 1024 * 1024,
@@ -244,12 +314,30 @@ class HyperspaceClient {
244
314
  }
245
315
  }
246
316
  // ... (create/delete unchanged) ...
247
- createCollection(name, dimension, metric) {
317
+ createCollection(name, schema) {
248
318
  return new Promise((resolve, reject) => {
249
319
  const req = new hyperspace_pb_1.CreateCollectionRequest();
250
320
  req.setName(name);
251
- req.setDimension(dimension);
252
- req.setMetric(metric);
321
+ const protoSchema = new hyperspace_pb.CollectionSchema();
322
+ const components = schema.components.map(c => {
323
+ const comp = new hyperspace_pb.VectorComponent();
324
+ comp.setName(c.name);
325
+ comp.setMetric(c.metric);
326
+ comp.setFullDimension(c.fullDimension);
327
+ comp.setWeight(c.weight);
328
+ return comp;
329
+ });
330
+ protoSchema.setComponentsList(components);
331
+ const pipeline = schema.cascadePipeline.map(l => {
332
+ const layer = new hyperspace_pb.MrlLayer();
333
+ layer.setComponentName(l.componentName);
334
+ layer.setCutoffDimension(l.cutoffDimension);
335
+ layer.setStoreInRam(l.storeInRam);
336
+ layer.setRerankTopK(l.rerankTopK);
337
+ return layer;
338
+ });
339
+ protoSchema.setCascadePipelineList(pipeline);
340
+ req.setSchema(protoSchema);
253
341
  this.client.createCollection(req, this.metadata, (err, resp) => {
254
342
  if (err)
255
343
  return reject(err);
@@ -268,22 +356,79 @@ class HyperspaceClient {
268
356
  });
269
357
  });
270
358
  }
359
+ freezeCollection(name) {
360
+ return new Promise((resolve, reject) => {
361
+ const req = new hyperspace_pb.FreezeCollectionRequest();
362
+ req.setName(name);
363
+ this.client.freezeCollection(req, this.metadata, (err, resp) => {
364
+ if (err)
365
+ return reject(err);
366
+ resolve(resp.getStatus());
367
+ });
368
+ });
369
+ }
370
+ unfreezeCollection(name) {
371
+ return new Promise((resolve, reject) => {
372
+ const req = new hyperspace_pb.UnfreezeCollectionRequest();
373
+ req.setName(name);
374
+ this.client.unfreezeCollection(req, this.metadata, (err, resp) => {
375
+ if (err)
376
+ return reject(err);
377
+ resolve(resp.getStatus());
378
+ });
379
+ });
380
+ }
271
381
  listCollections() {
272
382
  return new Promise((resolve, reject) => {
273
383
  const req = new hyperspace_pb_1.Empty();
274
384
  this.client.listCollections(req, this.metadata, (err, resp) => {
275
385
  if (err)
276
386
  return reject(err);
277
- const list = resp.getCollectionsList().map(c => ({
278
- name: c.getName(),
279
- count: c.getCount(),
280
- dimension: c.getDimension(),
281
- metric: c.getMetric()
282
- }));
387
+ const list = resp.getCollectionsList().map(c => {
388
+ const info = {
389
+ name: c.getName(),
390
+ count: c.getCount()
391
+ };
392
+ const protoSchema = c.getSchema();
393
+ if (protoSchema) {
394
+ info.schema = {
395
+ components: protoSchema.getComponentsList().map((comp) => ({
396
+ name: comp.getName(),
397
+ metric: comp.getMetric(),
398
+ fullDimension: comp.getFullDimension(),
399
+ weight: comp.getWeight()
400
+ })),
401
+ cascadePipeline: protoSchema.getCascadePipelineList().map((layer) => ({
402
+ componentName: layer.getComponentName(),
403
+ cutoffDimension: layer.getCutoffDimension(),
404
+ storeInRam: layer.getStoreInRam(),
405
+ rerankTopK: layer.getRerankTopK()
406
+ }))
407
+ };
408
+ }
409
+ return info;
410
+ });
283
411
  resolve(list);
284
412
  });
285
413
  });
286
414
  }
415
+ getPoints(ids, collection = '') {
416
+ return new Promise((resolve, reject) => {
417
+ const req = new hyperspace_pb_1.GetPointsRequest();
418
+ req.setCollection(collection);
419
+ req.setIdsList(ids);
420
+ this.client.getPoints(req, this.metadata, (err, resp) => {
421
+ if (err)
422
+ return reject(err);
423
+ const points = resp.getPointsList().map((p) => ({
424
+ id: p.getId(),
425
+ vector: p.getVectorList(),
426
+ metadata: p.getMetadataMap().toObject()
427
+ }));
428
+ resolve(points);
429
+ });
430
+ });
431
+ }
287
432
  delete(id, collection = '') {
288
433
  return new Promise((resolve, reject) => {
289
434
  const req = new hyperspace_pb.DeleteRequest();
@@ -296,7 +441,8 @@ class HyperspaceClient {
296
441
  });
297
442
  });
298
443
  }
299
- insert(id, vector, meta, collection = '', durability = hyperspace_pb_1.DurabilityLevel.DEFAULT_LEVEL, typedMetadata) {
444
+ insert(id, vector, meta, collection = '', durability = hyperspace_pb_1.DurabilityLevel.DEFAULT_LEVEL, typedMetadata, payload // Sidecar Payload Storage (v3.2)
445
+ ) {
300
446
  return new Promise((resolve, reject) => {
301
447
  const req = new hyperspace_pb_1.InsertRequest();
302
448
  req.setVectorList(HyperspaceClient.toVectorList(vector));
@@ -315,6 +461,9 @@ class HyperspaceClient {
315
461
  req.setOriginNodeId('');
316
462
  req.setLogicalClock(0);
317
463
  req.setDurability(durability);
464
+ if (payload) {
465
+ req.setPayload(payload);
466
+ }
318
467
  this.client.insert(req, this.metadata, (err, resp) => {
319
468
  if (err)
320
469
  return reject(err);
@@ -388,43 +537,40 @@ class HyperspaceClient {
388
537
  req.setVectorList(HyperspaceClient.toVectorList(vector));
389
538
  req.setTopK(topK);
390
539
  req.setCollection(collection);
540
+ if (options === null || options === void 0 ? void 0 : options.filter) {
541
+ const map = req.getFilterMap();
542
+ for (const k in options.filter) {
543
+ map.set(k, options.filter[k]);
544
+ }
545
+ }
546
+ if ((options === null || options === void 0 ? void 0 : options.restartFactor) !== undefined) {
547
+ const map = req.getFilterMap();
548
+ map.set('wave_restart_factor', options.restartFactor.toString());
549
+ }
550
+ if ((options === null || options === void 0 ? void 0 : options.useWave) !== undefined) {
551
+ req.setUseWave(options.useWave);
552
+ }
391
553
  if (options === null || options === void 0 ? void 0 : options.filters) {
392
- const protoFilters = options.filters.map(f => {
393
- const pf = new hyperspace_pb.Filter();
394
- if (f.match) {
395
- const m = new hyperspace_pb.Match();
396
- m.setKey(f.match.key);
397
- m.setValue(f.match.value);
398
- pf.setMatch(m);
399
- }
400
- else if (f.range) {
401
- const r = new hyperspace_pb.Range();
402
- r.setKey(f.range.key);
403
- if (f.range.gte !== undefined) {
404
- if (Number.isInteger(f.range.gte))
405
- r.setGte(f.range.gte);
406
- else
407
- r.setGteF64(f.range.gte);
408
- }
409
- if (f.range.lte !== undefined) {
410
- if (Number.isInteger(f.range.lte))
411
- r.setLte(f.range.lte);
412
- else
413
- r.setLteF64(f.range.lte);
414
- }
415
- pf.setRange(r);
416
- }
417
- return pf;
418
- });
419
- req.setFiltersList(protoFilters);
554
+ req.setFiltersList(options.filters.map(f => this.toProtoFilter(f)));
420
555
  }
421
556
  if (options === null || options === void 0 ? void 0 : options.hybridQuery)
422
557
  req.setHybridQuery(options.hybridQuery);
423
558
  if ((options === null || options === void 0 ? void 0 : options.hybridAlpha) !== undefined)
424
559
  req.setHybridAlpha(options.hybridAlpha);
560
+ if ((options === null || options === void 0 ? void 0 : options.mrlDimension) !== undefined)
561
+ req.setMrlDimension(options.mrlDimension);
562
+ if ((options === null || options === void 0 ? void 0 : options.useWasserstein) !== undefined)
563
+ req.setUseWasserstein(options.useWasserstein);
564
+ if ((options === null || options === void 0 ? void 0 : options.includePayload) !== undefined)
565
+ req.setIncludePayload(options.includePayload);
566
+ if (options === null || options === void 0 ? void 0 : options.componentWeights) {
567
+ const map = req.getComponentWeightsMap();
568
+ for (const k in options.componentWeights) {
569
+ map.set(k, options.componentWeights[k]);
570
+ }
571
+ }
425
572
  if (options === null || options === void 0 ? void 0 : options.bm25) {
426
- // @ts-ignore: Bm25Options might not be in generated proto yet
427
- const bm25Msg = new hyperspace_pb.Bm25Options();
573
+ const bm25Msg = new hyperspace_pb_1.Bm25Options();
428
574
  if (options.bm25.method !== undefined)
429
575
  bm25Msg.setMethod(options.bm25.method);
430
576
  if (options.bm25.k1 !== undefined)
@@ -439,7 +585,6 @@ class HyperspaceClient {
439
585
  bm25Msg.setNgrams(options.bm25.ngrams);
440
586
  if (options.bm25.fusionMethod !== undefined)
441
587
  bm25Msg.setFusionMethod(options.bm25.fusionMethod);
442
- // @ts-ignore
443
588
  req.setBm25Options(bm25Msg);
444
589
  }
445
590
  this.client.search(req, this.metadata, (err, resp) => {
@@ -457,7 +602,8 @@ class HyperspaceClient {
457
602
  id: r.getId(),
458
603
  distance: r.getDistance(),
459
604
  metadata: meta,
460
- typedMetadata: HyperspaceClient.parseTypedMetadata(r.getTypedMetadataMap())
605
+ typedMetadata: HyperspaceClient.parseTypedMetadata(r.getTypedMetadataMap()),
606
+ payload: r.getPayload_asU8()
461
607
  };
462
608
  });
463
609
  resolve(results);
@@ -471,38 +617,10 @@ class HyperspaceClient {
471
617
  req.setTopK(topK);
472
618
  req.setCollection(collection);
473
619
  if (options === null || options === void 0 ? void 0 : options.filters) {
474
- const protoFilters = options.filters.map(f => {
475
- const pf = new hyperspace_pb.Filter();
476
- if (f.match) {
477
- const m = new hyperspace_pb.Match();
478
- m.setKey(f.match.key);
479
- m.setValue(f.match.value);
480
- pf.setMatch(m);
481
- }
482
- else if (f.range) {
483
- const r = new hyperspace_pb.Range();
484
- r.setKey(f.range.key);
485
- if (f.range.gte !== undefined) {
486
- if (Number.isInteger(f.range.gte))
487
- r.setGte(f.range.gte);
488
- else
489
- r.setGteF64(f.range.gte);
490
- }
491
- if (f.range.lte !== undefined) {
492
- if (Number.isInteger(f.range.lte))
493
- r.setLte(f.range.lte);
494
- else
495
- r.setLteF64(f.range.lte);
496
- }
497
- pf.setRange(r);
498
- }
499
- return pf;
500
- });
501
- req.setFiltersList(protoFilters);
620
+ req.setFiltersList(options.filters.map(f => this.toProtoFilter(f)));
502
621
  }
503
622
  if (options === null || options === void 0 ? void 0 : options.bm25) {
504
- // @ts-ignore
505
- const bm25Msg = new hyperspace_pb.Bm25Options();
623
+ const bm25Msg = new hyperspace_pb_1.Bm25Options();
506
624
  if (options.bm25.method !== undefined)
507
625
  bm25Msg.setMethod(options.bm25.method);
508
626
  if (options.bm25.k1 !== undefined)
@@ -517,13 +635,14 @@ class HyperspaceClient {
517
635
  bm25Msg.setNgrams(options.bm25.ngrams);
518
636
  if (options.bm25.fusionMethod !== undefined)
519
637
  bm25Msg.setFusionMethod(options.bm25.fusionMethod);
520
- // @ts-ignore
521
638
  req.setBm25Options(bm25Msg);
522
639
  }
523
640
  if ((options === null || options === void 0 ? void 0 : options.hybridAlpha) !== undefined) {
524
- // @ts-ignore
525
641
  req.setHybridAlpha(options.hybridAlpha);
526
642
  }
643
+ if ((options === null || options === void 0 ? void 0 : options.includePayload) !== undefined) {
644
+ req.setIncludePayload(options.includePayload);
645
+ }
527
646
  this.client.searchText(req, this.metadata, (err, resp) => {
528
647
  if (err)
529
648
  return reject(err);
@@ -539,7 +658,8 @@ class HyperspaceClient {
539
658
  id: r.getId(),
540
659
  distance: r.getDistance(),
541
660
  metadata: meta,
542
- typedMetadata: HyperspaceClient.parseTypedMetadata(r.getTypedMetadataMap())
661
+ typedMetadata: HyperspaceClient.parseTypedMetadata(r.getTypedMetadataMap()),
662
+ payload: r.getPayload_asU8()
543
663
  };
544
664
  });
545
665
  resolve(results);
@@ -571,7 +691,8 @@ class HyperspaceClient {
571
691
  id: r.getId(),
572
692
  distance: r.getDistance(),
573
693
  metadata: meta,
574
- typedMetadata: HyperspaceClient.parseTypedMetadata(r.getTypedMetadataMap())
694
+ typedMetadata: HyperspaceClient.parseTypedMetadata(r.getTypedMetadataMap()),
695
+ payload: r.getPayload_asU8()
575
696
  };
576
697
  }));
577
698
  resolve(batch);
@@ -722,34 +843,7 @@ class HyperspaceClient {
722
843
  }
723
844
  }
724
845
  if (options === null || options === void 0 ? void 0 : options.filters) {
725
- const protoFilters = options.filters.map(f => {
726
- const pf = new hyperspace_pb.Filter();
727
- if (f.match) {
728
- const m = new hyperspace_pb.Match();
729
- m.setKey(f.match.key);
730
- m.setValue(f.match.value);
731
- pf.setMatch(m);
732
- }
733
- else if (f.range) {
734
- const r = new hyperspace_pb.Range();
735
- r.setKey(f.range.key);
736
- if (f.range.gte !== undefined) {
737
- if (Number.isInteger(f.range.gte))
738
- r.setGte(f.range.gte);
739
- else
740
- r.setGteF64(f.range.gte);
741
- }
742
- if (f.range.lte !== undefined) {
743
- if (Number.isInteger(f.range.lte))
744
- r.setLte(f.range.lte);
745
- else
746
- r.setLteF64(f.range.lte);
747
- }
748
- pf.setRange(r);
749
- }
750
- return pf;
751
- });
752
- req.setFiltersList(protoFilters);
846
+ req.setFiltersList(options.filters.map(f => this.toProtoFilter(f)));
753
847
  }
754
848
  this.client.traverse(req, this.metadata, (err, resp) => {
755
849
  if (err)
@@ -836,6 +930,251 @@ class HyperspaceClient {
836
930
  }
837
931
  return stream;
838
932
  }
933
+ getCollectionStats(name) {
934
+ return new Promise((resolve, reject) => {
935
+ const req = new hyperspace_pb_1.CollectionStatsRequest();
936
+ req.setName(name);
937
+ this.client.getCollectionStats(req, this.metadata, (err, resp) => {
938
+ if (err)
939
+ return reject(err);
940
+ const stats = {
941
+ count: resp.getCount(),
942
+ indexingQueue: resp.getIndexingQueue(),
943
+ diskUsageBytes: resp.getDiskUsageBytes(),
944
+ ramUsageBytes: resp.getRamUsageBytes(),
945
+ activeTasks: resp.getActiveTasks()
946
+ };
947
+ const protoSchema = resp.getSchema();
948
+ if (protoSchema) {
949
+ stats.schema = {
950
+ components: protoSchema.getComponentsList().map((comp) => ({
951
+ name: comp.getName(),
952
+ metric: comp.getMetric(),
953
+ fullDimension: comp.getFullDimension(),
954
+ weight: comp.getWeight()
955
+ })),
956
+ cascadePipeline: protoSchema.getCascadePipelineList().map((layer) => ({
957
+ componentName: layer.getComponentName(),
958
+ cutoffDimension: layer.getCutoffDimension(),
959
+ storeInRam: layer.getStoreInRam(),
960
+ rerankTopK: layer.getRerankTopK()
961
+ }))
962
+ };
963
+ }
964
+ resolve(stats);
965
+ });
966
+ });
967
+ }
968
+ async exists(name) {
969
+ try {
970
+ await this.getCollectionStats(name);
971
+ return true;
972
+ }
973
+ catch (e) {
974
+ if (e.code === grpc.status.NOT_FOUND || (e.message && e.message.includes('not found'))) {
975
+ return false;
976
+ }
977
+ throw e;
978
+ }
979
+ }
980
+ async getCacheStats(name) {
981
+ const ip = this.host.split(':')[0];
982
+ const url = `http://${ip}:50050/api/collections/${name}/cache/stats`;
983
+ const headers = {};
984
+ if (this.apiKey)
985
+ headers['x-api-key'] = this.apiKey;
986
+ if (this.userId)
987
+ headers['x-hyperspace-user-id'] = this.userId;
988
+ const res = await fetch(url, { headers });
989
+ if (!res.ok) {
990
+ throw new Error(`Failed to get cache stats: ${res.statusText} (${await res.text()})`);
991
+ }
992
+ return res.json();
993
+ }
994
+ async clearCache(name) {
995
+ const ip = this.host.split(':')[0];
996
+ const url = `http://${ip}:50050/api/collections/${name}/cache/clear`;
997
+ const headers = { 'Content-Type': 'application/json' };
998
+ if (this.apiKey)
999
+ headers['x-api-key'] = this.apiKey;
1000
+ if (this.userId)
1001
+ headers['x-hyperspace-user-id'] = this.userId;
1002
+ const res = await fetch(url, {
1003
+ method: 'POST',
1004
+ headers,
1005
+ body: JSON.stringify({})
1006
+ });
1007
+ if (!res.ok) {
1008
+ throw new Error(`Failed to clear cache: ${res.statusText} (${await res.text()})`);
1009
+ }
1010
+ const data = await res.json();
1011
+ return data.status === 'success';
1012
+ }
1013
+ async updateCacheConfig(name, policy, annThreshold) {
1014
+ const ip = this.host.split(':')[0];
1015
+ const url = `http://${ip}:50050/api/collections/${name}/cache/config`;
1016
+ const headers = { 'Content-Type': 'application/json' };
1017
+ if (this.apiKey)
1018
+ headers['x-api-key'] = this.apiKey;
1019
+ if (this.userId)
1020
+ headers['x-hyperspace-user-id'] = this.userId;
1021
+ const res = await fetch(url, {
1022
+ method: 'POST',
1023
+ headers,
1024
+ body: JSON.stringify({
1025
+ policy,
1026
+ ann_threshold: annThreshold
1027
+ })
1028
+ });
1029
+ if (!res.ok) {
1030
+ throw new Error(`Failed to update cache config: ${res.statusText} (${await res.text()})`);
1031
+ }
1032
+ const data = await res.json();
1033
+ return data.status === 'success';
1034
+ }
1035
+ updateCollection(name, config) {
1036
+ return new Promise((resolve, reject) => {
1037
+ const req = new hyperspace_pb_1.ConfigUpdate();
1038
+ req.setCollection(name);
1039
+ if (config.efSearch !== undefined)
1040
+ req.setEfSearch(config.efSearch);
1041
+ if (config.efConstruction !== undefined)
1042
+ req.setEfConstruction(config.efConstruction);
1043
+ if (config.m !== undefined)
1044
+ req.setM(config.m);
1045
+ this.client.configure(req, this.metadata, (err, resp) => {
1046
+ if (err)
1047
+ return reject(err);
1048
+ resolve(resp.getStatus() === 'success' || (!!resp.getStatus() && resp.getStatus().includes('updated')));
1049
+ });
1050
+ });
1051
+ }
1052
+ createSnapshot() {
1053
+ return new Promise((resolve, reject) => {
1054
+ this.client.triggerSnapshot(new hyperspace_pb_1.Empty(), this.metadata, (err, resp) => {
1055
+ if (err)
1056
+ return reject(err);
1057
+ resolve(resp.getStatus() === 'success');
1058
+ });
1059
+ });
1060
+ }
1061
+ vacuum() {
1062
+ return new Promise((resolve, reject) => {
1063
+ this.client.triggerVacuum(new hyperspace_pb_1.Empty(), this.metadata, (err, resp) => {
1064
+ if (err)
1065
+ return reject(err);
1066
+ resolve(resp.getStatus() === 'success');
1067
+ });
1068
+ });
1069
+ }
1070
+ getMetrics(onData, onError) {
1071
+ const req = new hyperspace_pb_1.MonitorRequest();
1072
+ const stream = this.client.monitor(req, this.metadata);
1073
+ stream.on('data', onData);
1074
+ if (onError) {
1075
+ stream.on('error', onError);
1076
+ }
1077
+ return stream;
1078
+ }
1079
+ searchMultiCollection(collections, query) {
1080
+ return new Promise((resolve, reject) => {
1081
+ const req = new hyperspace_pb_1.SearchMultiCollectionRequest();
1082
+ req.setCollectionsList(collections);
1083
+ req.setVectorList(HyperspaceClient.toVectorList(query));
1084
+ req.setTopK(10);
1085
+ this.client.searchMultiCollection(req, this.metadata, (err, resp) => {
1086
+ if (err)
1087
+ return reject(err);
1088
+ resolve(resp.toObject());
1089
+ });
1090
+ });
1091
+ }
1092
+ triggerReconsolidation(collection, targetVector, learningRate = 0.01) {
1093
+ return new Promise((resolve, reject) => {
1094
+ const req = new hyperspace_pb_1.ReconsolidationRequest();
1095
+ req.setCollection(collection);
1096
+ req.setTargetVectorList(targetVector);
1097
+ req.setLearningRate(learningRate);
1098
+ this.client.triggerReconsolidation(req, this.metadata, (err, resp) => {
1099
+ if (err)
1100
+ return reject(err);
1101
+ resolve(resp.getStatus() === 'success');
1102
+ });
1103
+ });
1104
+ }
1105
+ getSubsumptionTree(rootId, maxDepth = 3, collection = '') {
1106
+ return new Promise((resolve, reject) => {
1107
+ const req = new hyperspace_pb.GetSubsumptionTreeRequest();
1108
+ req.setRootId(rootId);
1109
+ req.setMaxDepth(maxDepth);
1110
+ req.setCollection(collection);
1111
+ this.client.getSubsumptionTree(req, this.metadata, (err, resp) => {
1112
+ if (err)
1113
+ return reject(err);
1114
+ const nodes = resp.getNodesList().map((n) => ({
1115
+ id: n.getId(),
1116
+ metadata: n.getMetadataMap().toObject(),
1117
+ edgeTypes: n.getEdgeTypesList()
1118
+ }));
1119
+ resolve(nodes);
1120
+ });
1121
+ });
1122
+ }
1123
+ async exploreGraph(startId, maxDepth = 2, maxNodes = 256, collection = '') {
1124
+ const req = new hyperspace_pb_1.TraverseRequest();
1125
+ req.setStartId(startId);
1126
+ req.setMaxDepth(maxDepth);
1127
+ req.setMaxNodes(maxNodes);
1128
+ req.setCollection(collection);
1129
+ req.setTraversalMode(1); // DIFFUSIVE
1130
+ req.setBreadthLimit(10);
1131
+ return new Promise((resolve, reject) => {
1132
+ this.client.traverse(req, this.metadata, (err, resp) => {
1133
+ if (err)
1134
+ return reject(err);
1135
+ const nodes = resp.getNodesList().map((n) => ({
1136
+ id: n.getId(),
1137
+ metadata: n.getMetadataMap().toObject(),
1138
+ edgeTypes: n.getEdgeTypesList(),
1139
+ neighbors: n.getNeighborsList()
1140
+ }));
1141
+ resolve({
1142
+ nodes,
1143
+ centerId: startId,
1144
+ count: nodes.length
1145
+ });
1146
+ });
1147
+ });
1148
+ }
1149
+ async predictMomentum(trajectoryIds, steps = 1.0, collection = '', curvature = 1.0) {
1150
+ if (trajectoryIds.length < 2)
1151
+ return [];
1152
+ const pts = await this.getPoints(trajectoryIds, collection);
1153
+ const idToVec = new Map();
1154
+ pts.forEach(p => idToVec.set(p.id, p.vector));
1155
+ const vectors = trajectoryIds.map(id => idToVec.get(id)).filter(v => !!v);
1156
+ if (vectors.length < 2)
1157
+ return [];
1158
+ const past = vectors[vectors.length - 2];
1159
+ const current = vectors[vectors.length - 1];
1160
+ const { koopmanExtrapolate } = require('./math');
1161
+ return koopmanExtrapolate(past, current, steps, curvature);
1162
+ }
1163
+ async getTrustScore(trajectoryIds, collection = '', curvature = 1.0) {
1164
+ const pts = await this.getPoints(trajectoryIds, collection);
1165
+ const idToVec = new Map();
1166
+ pts.forEach(p => idToVec.set(p.id, p.vector));
1167
+ const vectors = trajectoryIds.map(id => idToVec.get(id)).filter(v => !!v);
1168
+ if (vectors.length < 3)
1169
+ return 0.0;
1170
+ const { lyapunovConvergence } = require('./math');
1171
+ try {
1172
+ return lyapunovConvergence(vectors, curvature);
1173
+ }
1174
+ catch (e) {
1175
+ return 1.0;
1176
+ }
1177
+ }
839
1178
  close() {
840
1179
  this.client.close();
841
1180
  }