@h-ai/vecdb 0.1.0-alpha.32 → 0.1.0-alpha.34

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/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { core, ok, err } from '@h-ai/core';
3
+ import { spawn } from 'child_process';
4
+ import { setTimeout } from 'timers/promises';
3
5
  import { createHash } from 'crypto';
4
6
 
5
7
  // src/vecdb-config.ts
@@ -112,10 +114,31 @@ var QdrantConfigSchema = z.object({
112
114
  metric: DistanceMetricSchema.optional(),
113
115
  ...OperationLogConfigFieldSchema
114
116
  });
117
+ var ChromaConfigSchema = z.object({
118
+ type: z.literal("chroma"),
119
+ /** 本地持久化路径(嵌入式模式:提供且无 url 时自动拉起本地服务) */
120
+ path: z.string().optional(),
121
+ /** 已有 Chroma 服务 URL(提供时直连,不自动拉起进程) */
122
+ url: z.string().url().optional(),
123
+ /** 主机(默认 localhost) */
124
+ host: z.string().default("localhost"),
125
+ /** 端口(默认 8000) */
126
+ port: z.number().int().min(1).max(65535).default(8e3),
127
+ /** API Key(可选,连接受保护的 Chroma 服务时使用) */
128
+ apiKey: z.string().optional(),
129
+ /** 拉起本地服务的可执行命令(默认 'chroma',可指定绝对路径) */
130
+ serverCommand: z.string().default("chroma"),
131
+ /** 拉起本地服务的就绪等待超时(毫秒,默认 30000) */
132
+ startupTimeout: z.number().int().positive().default(3e4),
133
+ /** 距离度量(默认 cosine) */
134
+ metric: DistanceMetricSchema.optional(),
135
+ ...OperationLogConfigFieldSchema
136
+ });
115
137
  var VecdbConfigSchema = z.discriminatedUnion("type", [
116
138
  LancedbConfigSchema,
117
139
  PgvectorConfigSchema,
118
- QdrantConfigSchema
140
+ QdrantConfigSchema,
141
+ ChromaConfigSchema
119
142
  ]);
120
143
  var VecdbErrorInfo = {
121
144
  CONNECTION_FAILED: "001:500",
@@ -302,8 +325,295 @@ function createBaseVectorOps(ctx, driver) {
302
325
  };
303
326
  }
304
327
 
305
- // src/providers/vecdb-provider-lancedb.ts
306
- var logger = core.logger.child({ module: "vecdb", scope: "lancedb" });
328
+ // src/providers/vecdb-provider-chroma.ts
329
+ var logger = core.logger.child({ module: "vecdb", scope: "chroma" });
330
+ var DIMENSION_METADATA_KEY = "hai_dimension";
331
+ var SPACE_METADATA_KEY = "hnsw:space";
332
+ var HEARTBEAT_POLL_INTERVAL = 300;
333
+ function isChromaModule(value) {
334
+ return typeof value === "object" && value !== null && typeof value.ChromaClient === "function";
335
+ }
336
+ var NOOP_EMBEDDING_FUNCTION = {
337
+ name: "hai-noop",
338
+ async generate() {
339
+ throw new Error("Chroma embedding function should not be called: vectors are provided explicitly");
340
+ }
341
+ };
342
+ function toChromaSpace(metric) {
343
+ if (metric === "euclidean")
344
+ return "l2";
345
+ if (metric === "dot")
346
+ return "ip";
347
+ return "cosine";
348
+ }
349
+ function fromChromaSpace(space) {
350
+ if (space === "l2")
351
+ return "euclidean";
352
+ if (space === "ip")
353
+ return "dot";
354
+ return "cosine";
355
+ }
356
+ function distanceToScore(distance, metric) {
357
+ if (metric === "cosine")
358
+ return Math.max(0, Math.min(1, 1 - distance));
359
+ return 1 / (1 + Math.max(0, distance));
360
+ }
361
+ function buildWhere(filter) {
362
+ if (!filter)
363
+ return void 0;
364
+ const entries = Object.entries(filter);
365
+ if (entries.length === 0)
366
+ return void 0;
367
+ if (entries.length === 1)
368
+ return { [entries[0][0]]: entries[0][1] };
369
+ return { $and: entries.map(([key, value]) => ({ [key]: value })) };
370
+ }
371
+ function createChromaProvider() {
372
+ let client = null;
373
+ let config = null;
374
+ let serverProcess = null;
375
+ function isMissingModuleError(error) {
376
+ const message = error instanceof Error ? error.message : String(error);
377
+ return message.includes("chromadb");
378
+ }
379
+ async function loadChromaModule() {
380
+ try {
381
+ const mod = await import('chromadb');
382
+ if (!isChromaModule(mod)) {
383
+ const error = new Error("chromadb driver module does not export ChromaClient");
384
+ logger.error("Failed to load Chroma driver", { error: error.message });
385
+ return err(HaiVecdbError.DRIVER_NOT_FOUND, vecdbM("vecdb_driverNotFound", { params: { driver: "chromadb" } }), error);
386
+ }
387
+ return ok(mod);
388
+ } catch (error) {
389
+ if (isMissingModuleError(error)) {
390
+ logger.error("Failed to load Chroma driver", { error: error instanceof Error ? error.message : String(error) });
391
+ return err(HaiVecdbError.DRIVER_NOT_FOUND, vecdbM("vecdb_driverNotFound", { params: { driver: "chromadb" } }), error);
392
+ }
393
+ throw error;
394
+ }
395
+ }
396
+ function startEmbeddedServer(chromaConfig) {
397
+ const args = ["run", "--path", chromaConfig.path ?? "./data/chroma", "--host", chromaConfig.host, "--port", String(chromaConfig.port)];
398
+ logger.info("Starting embedded Chroma server", { command: chromaConfig.serverCommand, host: chromaConfig.host, port: chromaConfig.port });
399
+ const proc = spawn(chromaConfig.serverCommand, args, { stdio: "ignore" });
400
+ proc.on("error", (error) => {
401
+ logger.error("Chroma server process error", { error: error.message });
402
+ });
403
+ serverProcess = proc;
404
+ }
405
+ function stopEmbeddedServer() {
406
+ if (!serverProcess)
407
+ return;
408
+ try {
409
+ serverProcess.kill();
410
+ } catch (error) {
411
+ logger.warn("Failed to stop Chroma server", { error: error instanceof Error ? error.message : String(error) });
412
+ }
413
+ serverProcess = null;
414
+ }
415
+ async function waitForHeartbeat(chromaClient, timeout) {
416
+ const deadline = Date.now() + timeout;
417
+ let lastError;
418
+ while (Date.now() < deadline) {
419
+ try {
420
+ await chromaClient.heartbeat();
421
+ return;
422
+ } catch (error) {
423
+ lastError = error;
424
+ await setTimeout(HEARTBEAT_POLL_INTERVAL);
425
+ }
426
+ }
427
+ throw new Error(`Chroma heartbeat timed out after ${timeout}ms: ${lastError instanceof Error ? lastError.message : String(lastError)}`);
428
+ }
429
+ async function getCollection(name) {
430
+ return client.getCollection({ name, embeddingFunction: NOOP_EMBEDDING_FUNCTION });
431
+ }
432
+ function readDimension(collection) {
433
+ const value = collection.metadata?.[DIMENSION_METADATA_KEY];
434
+ return typeof value === "number" ? value : 0;
435
+ }
436
+ function validateDimension(expected, actual) {
437
+ if (expected === 0 || expected === actual)
438
+ return null;
439
+ return err(
440
+ HaiVecdbError.DIMENSION_MISMATCH,
441
+ vecdbM("vecdb_dimensionMismatch", { params: { expected: String(expected), actual: String(actual) } })
442
+ );
443
+ }
444
+ const ctx = { isConnected: () => client !== null, logger, operationLog: () => config?.operationLog };
445
+ const collectionDriver = {
446
+ async create(name, options) {
447
+ logger.debug("Creating collection", { name, dimension: options.dimension, metric: options.metric });
448
+ const existing = await client.listCollections();
449
+ const exists = existing.some((item) => (typeof item === "string" ? item : item.name) === name);
450
+ if (exists)
451
+ return err(HaiVecdbError.COLLECTION_ALREADY_EXISTS, vecdbM("vecdb_collectionAlreadyExists", { params: { name } }));
452
+ const metric = options.metric ?? config?.metric ?? "cosine";
453
+ await client.getOrCreateCollection({
454
+ name,
455
+ metadata: { [SPACE_METADATA_KEY]: toChromaSpace(metric), [DIMENSION_METADATA_KEY]: options.dimension },
456
+ embeddingFunction: NOOP_EMBEDDING_FUNCTION
457
+ });
458
+ logger.info("Collection created", { name, dimension: options.dimension, metric });
459
+ return ok(void 0);
460
+ },
461
+ async drop(name) {
462
+ logger.debug("Dropping collection", { name });
463
+ const existing = await client.listCollections();
464
+ const exists = existing.some((item) => (typeof item === "string" ? item : item.name) === name);
465
+ if (!exists)
466
+ return err(HaiVecdbError.COLLECTION_NOT_FOUND, vecdbM("vecdb_collectionNotFound", { params: { name } }));
467
+ await client.deleteCollection({ name });
468
+ logger.info("Collection dropped", { name });
469
+ return ok(void 0);
470
+ },
471
+ async exists(name) {
472
+ logger.debug("Checking collection exists", { name });
473
+ const existing = await client.listCollections();
474
+ return ok(existing.some((item) => (typeof item === "string" ? item : item.name) === name));
475
+ },
476
+ async info(name) {
477
+ logger.debug("Getting collection info", { name });
478
+ const existing = await client.listCollections();
479
+ if (!existing.some((item) => (typeof item === "string" ? item : item.name) === name))
480
+ return err(HaiVecdbError.COLLECTION_NOT_FOUND, vecdbM("vecdb_collectionNotFound", { params: { name } }));
481
+ const collection = await getCollection(name);
482
+ const count = await collection.count();
483
+ return ok({
484
+ name,
485
+ dimension: readDimension(collection),
486
+ metric: fromChromaSpace(collection.metadata?.[SPACE_METADATA_KEY]),
487
+ count
488
+ });
489
+ },
490
+ async list() {
491
+ logger.debug("Listing collections");
492
+ const existing = await client.listCollections();
493
+ return ok(existing.map((item) => typeof item === "string" ? item : item.name));
494
+ }
495
+ };
496
+ function toWriteParams(documents) {
497
+ return {
498
+ ids: documents.map((doc) => doc.id),
499
+ embeddings: documents.map((doc) => doc.vector),
500
+ documents: documents.map((doc) => doc.content ?? null),
501
+ metadatas: documents.map((doc) => ({ ...doc.metadata, _content: doc.content ?? "" }))
502
+ };
503
+ }
504
+ const vectorDriver = {
505
+ async insert(collection, documents) {
506
+ logger.debug("Inserting vectors", { collection, count: documents.length });
507
+ const target = await getCollection(collection);
508
+ const expected = readDimension(target);
509
+ for (const doc of documents) {
510
+ const validation = validateDimension(expected, doc.vector.length);
511
+ if (validation)
512
+ return validation;
513
+ }
514
+ await target.add(toWriteParams(documents));
515
+ logger.info("Vectors inserted", { collection, count: documents.length });
516
+ return ok(void 0);
517
+ },
518
+ async upsert(collection, documents) {
519
+ logger.debug("Upserting vectors", { collection, count: documents.length });
520
+ const target = await getCollection(collection);
521
+ const expected = readDimension(target);
522
+ for (const doc of documents) {
523
+ const validation = validateDimension(expected, doc.vector.length);
524
+ if (validation)
525
+ return validation;
526
+ }
527
+ await target.upsert(toWriteParams(documents));
528
+ logger.info("Vectors upserted", { collection, count: documents.length });
529
+ return ok(void 0);
530
+ },
531
+ async delete(collection, ids) {
532
+ logger.debug("Deleting vectors", { collection, count: ids.length });
533
+ const target = await getCollection(collection);
534
+ await target.delete({ ids });
535
+ logger.info("Vectors deleted", { collection, count: ids.length });
536
+ return ok(void 0);
537
+ },
538
+ async search(collection, vector, options) {
539
+ const topK = options?.topK ?? 10;
540
+ const minScore = options?.minScore ?? 0;
541
+ logger.debug("Searching vectors", { collection, topK, hasFilter: !!options?.filter });
542
+ const target = await getCollection(collection);
543
+ const expected = readDimension(target);
544
+ const validation = validateDimension(expected, vector.length);
545
+ if (validation)
546
+ return validation;
547
+ const metric = fromChromaSpace(target.metadata?.[SPACE_METADATA_KEY]);
548
+ const response = await target.query({ queryEmbeddings: [vector], nResults: topK, where: buildWhere(options?.filter) });
549
+ const ids = response.ids[0] ?? [];
550
+ const distances = response.distances?.[0] ?? [];
551
+ const metadatas = response.metadatas?.[0] ?? [];
552
+ const results = [];
553
+ for (let i = 0; i < ids.length; i++) {
554
+ const score = distanceToScore(distances[i] ?? 0, metric);
555
+ if (score < minScore)
556
+ continue;
557
+ const metadata = metadatas[i] ?? {};
558
+ const { _content, ...rest } = metadata;
559
+ results.push({
560
+ id: ids[i],
561
+ score,
562
+ content: typeof _content === "string" && _content.length > 0 ? _content : void 0,
563
+ metadata: Object.keys(rest).length > 0 ? rest : void 0
564
+ });
565
+ }
566
+ return ok(results);
567
+ },
568
+ async count(collection) {
569
+ logger.debug("Counting vectors", { collection });
570
+ const target = await getCollection(collection);
571
+ return ok(await target.count());
572
+ }
573
+ };
574
+ return {
575
+ name: "chroma",
576
+ async connect(cfg) {
577
+ if (cfg.type !== "chroma")
578
+ return err(HaiVecdbError.UNSUPPORTED_TYPE, vecdbM("vecdb_unsupportedType", { params: { type: cfg.type } }));
579
+ const chromaConfig = cfg;
580
+ const embedded = !!chromaConfig.path && !chromaConfig.url;
581
+ const loadResult = await loadChromaModule();
582
+ if (!loadResult.success)
583
+ return loadResult;
584
+ try {
585
+ if (embedded)
586
+ startEmbeddedServer(chromaConfig);
587
+ const clientParams = chromaConfig.url ? { path: chromaConfig.url } : { host: chromaConfig.host, port: chromaConfig.port };
588
+ if (chromaConfig.apiKey)
589
+ clientParams.auth = { provider: "token", credentials: chromaConfig.apiKey, tokenHeaderType: "AUTHORIZATION" };
590
+ const chromaClient = new loadResult.data.ChromaClient(clientParams);
591
+ await waitForHeartbeat(chromaClient, embedded ? chromaConfig.startupTimeout : 5e3);
592
+ client = chromaClient;
593
+ config = chromaConfig;
594
+ logger.info("Chroma connected", { embedded, host: chromaConfig.host, port: chromaConfig.port });
595
+ return ok(void 0);
596
+ } catch (error) {
597
+ stopEmbeddedServer();
598
+ logger.error("Failed to connect to Chroma", { error: error instanceof Error ? error.message : String(error) });
599
+ return err(HaiVecdbError.CONNECTION_FAILED, vecdbM("vecdb_connectionFailed", { params: { error: String(error) } }), error);
600
+ }
601
+ },
602
+ async close() {
603
+ stopEmbeddedServer();
604
+ client = null;
605
+ config = null;
606
+ logger.info("Chroma connection closed");
607
+ return ok(void 0);
608
+ },
609
+ isConnected() {
610
+ return client !== null;
611
+ },
612
+ collection: createBaseCollectionOps(ctx, collectionDriver),
613
+ vector: createBaseVectorOps(ctx, vectorDriver)
614
+ };
615
+ }
616
+ var logger2 = core.logger.child({ module: "vecdb", scope: "lancedb" });
307
617
  function escapeLanceFilterValue(value) {
308
618
  return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/%/g, "\\%").replace(/_/g, "\\_");
309
619
  }
@@ -316,7 +626,7 @@ function createLancedbProvider() {
316
626
  const mod = await import('@lancedb/lancedb');
317
627
  return ok(mod);
318
628
  } catch (error) {
319
- logger.error("Failed to load @lancedb/lancedb", { error });
629
+ logger2.error("Failed to load @lancedb/lancedb", { error });
320
630
  return err(HaiVecdbError.DRIVER_NOT_FOUND, vecdbM("vecdb_driverNotFound", { params: { driver: "@lancedb/lancedb" } }), error);
321
631
  }
322
632
  }
@@ -363,10 +673,10 @@ function createLancedbProvider() {
363
673
  }
364
674
  return null;
365
675
  }
366
- const ctx = { isConnected: () => connection !== null, logger, operationLog: () => config?.operationLog };
676
+ const ctx = { isConnected: () => connection !== null, logger: logger2, operationLog: () => config?.operationLog };
367
677
  const collectionDriver = {
368
678
  async create(name, options) {
369
- logger.debug("Creating collection", { name, dimension: options.dimension, metric: options.metric });
679
+ logger2.debug("Creating collection", { name, dimension: options.dimension, metric: options.metric });
370
680
  const tableNames = await connection.tableNames();
371
681
  if (tableNames.includes(name)) {
372
682
  return err(HaiVecdbError.COLLECTION_ALREADY_EXISTS, vecdbM("vecdb_collectionAlreadyExists", { params: { name } }));
@@ -382,27 +692,27 @@ function createLancedbProvider() {
382
692
  const table = await connection.createTable(name, [initRecord]);
383
693
  await table.delete('id = "__init__"');
384
694
  collectionMetas.set(name, { dimension, metric });
385
- logger.info("Collection created", { name, dimension, metric });
695
+ logger2.info("Collection created", { name, dimension, metric });
386
696
  return ok(void 0);
387
697
  },
388
698
  async drop(name) {
389
- logger.debug("Dropping collection", { name });
699
+ logger2.debug("Dropping collection", { name });
390
700
  const tableNames = await connection.tableNames();
391
701
  if (!tableNames.includes(name)) {
392
702
  return err(HaiVecdbError.COLLECTION_NOT_FOUND, vecdbM("vecdb_collectionNotFound", { params: { name } }));
393
703
  }
394
704
  await connection.dropTable(name);
395
705
  collectionMetas.delete(name);
396
- logger.info("Collection dropped", { name });
706
+ logger2.info("Collection dropped", { name });
397
707
  return ok(void 0);
398
708
  },
399
709
  async exists(name) {
400
- logger.debug("Checking collection exists", { name });
710
+ logger2.debug("Checking collection exists", { name });
401
711
  const tableNames = await connection.tableNames();
402
712
  return ok(tableNames.includes(name));
403
713
  },
404
714
  async info(name) {
405
- logger.debug("Getting collection info", { name });
715
+ logger2.debug("Getting collection info", { name });
406
716
  const table = await openTable(name);
407
717
  if (!table) {
408
718
  return err(HaiVecdbError.COLLECTION_NOT_FOUND, vecdbM("vecdb_collectionNotFound", { params: { name } }));
@@ -417,14 +727,14 @@ function createLancedbProvider() {
417
727
  });
418
728
  },
419
729
  async list() {
420
- logger.debug("Listing collections");
730
+ logger2.debug("Listing collections");
421
731
  const tableNames = await connection.tableNames();
422
732
  return ok(tableNames);
423
733
  }
424
734
  };
425
735
  const vectorDriver = {
426
736
  async insert(collection, documents) {
427
- logger.debug("Inserting vectors", { collection, count: documents.length });
737
+ logger2.debug("Inserting vectors", { collection, count: documents.length });
428
738
  const table = await openTable(collection);
429
739
  if (!table) {
430
740
  return err(HaiVecdbError.COLLECTION_NOT_FOUND, vecdbM("vecdb_collectionNotFound", { params: { name: collection } }));
@@ -440,11 +750,11 @@ function createLancedbProvider() {
440
750
  metadata: JSON.stringify(doc.metadata ?? {})
441
751
  }));
442
752
  await table.add(records);
443
- logger.info("Vectors inserted", { collection, count: documents.length });
753
+ logger2.info("Vectors inserted", { collection, count: documents.length });
444
754
  return ok(void 0);
445
755
  },
446
756
  async upsert(collection, documents) {
447
- logger.debug("Upserting vectors", { collection, count: documents.length });
757
+ logger2.debug("Upserting vectors", { collection, count: documents.length });
448
758
  const table = await openTable(collection);
449
759
  if (!table) {
450
760
  return err(HaiVecdbError.COLLECTION_NOT_FOUND, vecdbM("vecdb_collectionNotFound", { params: { name: collection } }));
@@ -462,27 +772,27 @@ function createLancedbProvider() {
462
772
  if (typeof table.mergeInsert === "function") {
463
773
  await table.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(records);
464
774
  } else {
465
- logger.warn("LanceDB mergeInsert is unavailable, falling back to delete/add upsert");
775
+ logger2.warn("LanceDB mergeInsert is unavailable, falling back to delete/add upsert");
466
776
  const ids = documents.map((d) => `"${escapeLanceFilterValue(d.id)}"`).join(", ");
467
777
  await table.delete(`id IN (${ids})`);
468
778
  await table.add(records);
469
779
  }
470
- logger.info("Vectors upserted", { collection, count: documents.length });
780
+ logger2.info("Vectors upserted", { collection, count: documents.length });
471
781
  return ok(void 0);
472
782
  },
473
783
  async delete(collection, ids) {
474
- logger.debug("Deleting vectors", { collection, count: ids.length });
784
+ logger2.debug("Deleting vectors", { collection, count: ids.length });
475
785
  const table = await openTable(collection);
476
786
  if (!table) {
477
787
  return err(HaiVecdbError.COLLECTION_NOT_FOUND, vecdbM("vecdb_collectionNotFound", { params: { name: collection } }));
478
788
  }
479
789
  const idList = ids.map((id) => `"${escapeLanceFilterValue(id)}"`).join(", ");
480
790
  await table.delete(`id IN (${idList})`);
481
- logger.info("Vectors deleted", { collection, count: ids.length });
791
+ logger2.info("Vectors deleted", { collection, count: ids.length });
482
792
  return ok(void 0);
483
793
  },
484
794
  async search(collection, vector, options) {
485
- logger.debug("Searching vectors", { collection, topK: options?.topK, hasFilter: !!options?.filter });
795
+ logger2.debug("Searching vectors", { collection, topK: options?.topK, hasFilter: !!options?.filter });
486
796
  const table = await openTable(collection);
487
797
  if (!table) {
488
798
  return err(HaiVecdbError.COLLECTION_NOT_FOUND, vecdbM("vecdb_collectionNotFound", { params: { name: collection } }));
@@ -517,7 +827,7 @@ function createLancedbProvider() {
517
827
  return ok(searchResults);
518
828
  },
519
829
  async count(collection) {
520
- logger.debug("Counting vectors", { collection });
830
+ logger2.debug("Counting vectors", { collection });
521
831
  const table = await openTable(collection);
522
832
  if (!table) {
523
833
  return err(HaiVecdbError.COLLECTION_NOT_FOUND, vecdbM("vecdb_collectionNotFound", { params: { name: collection } }));
@@ -557,10 +867,10 @@ function createLancedbProvider() {
557
867
  } catch {
558
868
  }
559
869
  }));
560
- logger.info("LanceDB connected", { path: lanceConfig.path });
870
+ logger2.info("LanceDB connected", { path: lanceConfig.path });
561
871
  return ok(void 0);
562
872
  } catch (error) {
563
- logger.error("Failed to connect to LanceDB", { error });
873
+ logger2.error("Failed to connect to LanceDB", { error });
564
874
  return err(HaiVecdbError.CONNECTION_FAILED, vecdbM("vecdb_connectionFailed", { params: { error: String(error) } }), error);
565
875
  }
566
876
  },
@@ -568,7 +878,7 @@ function createLancedbProvider() {
568
878
  connection = null;
569
879
  config = null;
570
880
  collectionMetas.clear();
571
- logger.info("LanceDB connection closed");
881
+ logger2.info("LanceDB connection closed");
572
882
  return ok(void 0);
573
883
  },
574
884
  isConnected() {
@@ -578,7 +888,7 @@ function createLancedbProvider() {
578
888
  vector: createBaseVectorOps(ctx, vectorDriver)
579
889
  };
580
890
  }
581
- var logger2 = core.logger.child({ module: "vecdb", scope: "pgvector" });
891
+ var logger3 = core.logger.child({ module: "vecdb", scope: "pgvector" });
582
892
  function isPgModule(value) {
583
893
  if (typeof value !== "object" || value === null) {
584
894
  return false;
@@ -608,7 +918,7 @@ function createPgvectorProvider() {
608
918
  return "<=>";
609
919
  }
610
920
  }
611
- function distanceToScore(distance) {
921
+ function distanceToScore2(distance) {
612
922
  const metric = config?.metric ?? "cosine";
613
923
  switch (metric) {
614
924
  case "cosine":
@@ -630,13 +940,13 @@ function createPgvectorProvider() {
630
940
  const mod = await import('pg');
631
941
  if (!isPgModule(mod)) {
632
942
  const error = new Error("pg driver module does not export Pool");
633
- logger2.error("Failed to load pg driver", { error: error.message });
943
+ logger3.error("Failed to load pg driver", { error: error.message });
634
944
  return err(HaiVecdbError.DRIVER_NOT_FOUND, vecdbM("vecdb_driverNotFound", { params: { driver: "pg" } }), error);
635
945
  }
636
946
  return ok(mod);
637
947
  } catch (error) {
638
948
  if (isMissingModuleError(error, "pg")) {
639
- logger2.error("Failed to load pg driver", { error: error instanceof Error ? error.message : String(error) });
949
+ logger3.error("Failed to load pg driver", { error: error instanceof Error ? error.message : String(error) });
640
950
  return err(HaiVecdbError.DRIVER_NOT_FOUND, vecdbM("vecdb_driverNotFound", { params: { driver: "pg" } }), error);
641
951
  }
642
952
  throw error;
@@ -677,14 +987,14 @@ function createPgvectorProvider() {
677
987
  }
678
988
  return null;
679
989
  }
680
- const ctx = { isConnected: () => pool !== null, logger: logger2, operationLog: () => config?.operationLog };
990
+ const ctx = { isConnected: () => pool !== null, logger: logger3, operationLog: () => config?.operationLog };
681
991
  const collectionDriver = {
682
992
  async create(name, options) {
683
993
  const table = tableName(name);
684
994
  const dimension = options.dimension;
685
995
  const metric = options.metric ?? config?.metric ?? "cosine";
686
996
  const indexType = config?.indexType ?? "hnsw";
687
- logger2.debug("Creating collection", { name, dimension, metric, indexType });
997
+ logger3.debug("Creating collection", { name, dimension, metric, indexType });
688
998
  const checkResult = await pool.query(
689
999
  `SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = $1)`,
690
1000
  [table]
@@ -715,12 +1025,12 @@ function createPgvectorProvider() {
715
1025
  WITH (lists = 100)
716
1026
  `);
717
1027
  }
718
- logger2.info("Collection created", { name, dimension, metric, indexType });
1028
+ logger3.info("Collection created", { name, dimension, metric, indexType });
719
1029
  return ok(void 0);
720
1030
  },
721
1031
  async drop(name) {
722
1032
  const table = tableName(name);
723
- logger2.debug("Dropping collection", { name });
1033
+ logger3.debug("Dropping collection", { name });
724
1034
  const checkResult = await pool.query(
725
1035
  `SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = $1)`,
726
1036
  [table]
@@ -729,11 +1039,11 @@ function createPgvectorProvider() {
729
1039
  return err(HaiVecdbError.COLLECTION_NOT_FOUND, vecdbM("vecdb_collectionNotFound", { params: { name } }));
730
1040
  }
731
1041
  await pool.query(`DROP TABLE ${quoteIdent(table)}`);
732
- logger2.info("Collection dropped", { name });
1042
+ logger3.info("Collection dropped", { name });
733
1043
  return ok(void 0);
734
1044
  },
735
1045
  async exists(name) {
736
- logger2.debug("Checking collection exists", { name });
1046
+ logger3.debug("Checking collection exists", { name });
737
1047
  const result = await pool.query(
738
1048
  `SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = $1)`,
739
1049
  [tableName(name)]
@@ -741,7 +1051,7 @@ function createPgvectorProvider() {
741
1051
  return ok(result.rows[0].exists);
742
1052
  },
743
1053
  async info(name) {
744
- logger2.debug("Getting collection info", { name });
1054
+ logger3.debug("Getting collection info", { name });
745
1055
  const table = tableName(name);
746
1056
  const dimensionResult = await getCollectionDimension(name);
747
1057
  if (!dimensionResult.success) {
@@ -758,7 +1068,7 @@ function createPgvectorProvider() {
758
1068
  },
759
1069
  async list() {
760
1070
  const prefix = config?.tablePrefix ?? "vec_";
761
- logger2.debug("Listing collections");
1071
+ logger3.debug("Listing collections");
762
1072
  const result = await pool.query(
763
1073
  `SELECT table_name FROM information_schema.tables WHERE table_name LIKE $1 AND table_schema = 'public'`,
764
1074
  [`${prefix}%`]
@@ -772,7 +1082,7 @@ function createPgvectorProvider() {
772
1082
  const vectorDriver = {
773
1083
  async insert(collection, documents) {
774
1084
  const table = tableName(collection);
775
- logger2.debug("Inserting vectors", { collection, count: documents.length });
1085
+ logger3.debug("Inserting vectors", { collection, count: documents.length });
776
1086
  const dimensionResult = await getCollectionDimension(collection);
777
1087
  if (!dimensionResult.success) {
778
1088
  return dimensionResult;
@@ -794,12 +1104,12 @@ function createPgvectorProvider() {
794
1104
  `INSERT INTO ${qi} (id, vector, content, metadata) VALUES ${values.join(", ")}`,
795
1105
  params
796
1106
  );
797
- logger2.info("Vectors inserted", { collection, count: documents.length });
1107
+ logger3.info("Vectors inserted", { collection, count: documents.length });
798
1108
  return ok(void 0);
799
1109
  },
800
1110
  async upsert(collection, documents) {
801
1111
  const table = tableName(collection);
802
- logger2.debug("Upserting vectors", { collection, count: documents.length });
1112
+ logger3.debug("Upserting vectors", { collection, count: documents.length });
803
1113
  const dimensionResult = await getCollectionDimension(collection);
804
1114
  if (!dimensionResult.success) {
805
1115
  return dimensionResult;
@@ -825,15 +1135,15 @@ function createPgvectorProvider() {
825
1135
  metadata = EXCLUDED.metadata`,
826
1136
  params
827
1137
  );
828
- logger2.info("Vectors upserted", { collection, count: documents.length });
1138
+ logger3.info("Vectors upserted", { collection, count: documents.length });
829
1139
  return ok(void 0);
830
1140
  },
831
1141
  async delete(collection, ids) {
832
1142
  const table = tableName(collection);
833
- logger2.debug("Deleting vectors", { collection, count: ids.length });
1143
+ logger3.debug("Deleting vectors", { collection, count: ids.length });
834
1144
  const placeholders = ids.map((_, i) => `$${i + 1}`).join(", ");
835
1145
  await pool.query(`DELETE FROM ${quoteIdent(table)} WHERE id IN (${placeholders})`, ids);
836
- logger2.info("Vectors deleted", { collection, count: ids.length });
1146
+ logger3.info("Vectors deleted", { collection, count: ids.length });
837
1147
  return ok(void 0);
838
1148
  },
839
1149
  async search(collection, vector, options) {
@@ -841,7 +1151,7 @@ function createPgvectorProvider() {
841
1151
  const topK = options?.topK ?? 10;
842
1152
  const minScore = options?.minScore ?? 0;
843
1153
  const op = distanceOp();
844
- logger2.debug("Searching vectors", { collection, topK, hasFilter: !!options?.filter });
1154
+ logger3.debug("Searching vectors", { collection, topK, hasFilter: !!options?.filter });
845
1155
  const dimensionResult = await getCollectionDimension(collection);
846
1156
  if (!dimensionResult.success) {
847
1157
  return dimensionResult;
@@ -874,7 +1184,7 @@ function createPgvectorProvider() {
874
1184
  filterParams
875
1185
  );
876
1186
  const searchResults = result.rows.map((row) => {
877
- const score = distanceToScore(row.distance);
1187
+ const score = distanceToScore2(row.distance);
878
1188
  return {
879
1189
  id: row.id,
880
1190
  score,
@@ -886,7 +1196,7 @@ function createPgvectorProvider() {
886
1196
  },
887
1197
  async count(collection) {
888
1198
  const table = tableName(collection);
889
- logger2.debug("Counting vectors", { collection });
1199
+ logger3.debug("Counting vectors", { collection });
890
1200
  const result = await pool.query(`SELECT COUNT(*) as count FROM ${quoteIdent(table)}`);
891
1201
  return ok(Number.parseInt(String(result.rows[0].count), 10));
892
1202
  }
@@ -914,10 +1224,10 @@ function createPgvectorProvider() {
914
1224
  pool = new Pool(poolConfig);
915
1225
  await pool.query("CREATE EXTENSION IF NOT EXISTS vector");
916
1226
  config = pgConfig;
917
- logger2.info("pgvector connected", { host: pgConfig.host, database: pgConfig.database });
1227
+ logger3.info("pgvector connected", { host: pgConfig.host, database: pgConfig.database });
918
1228
  return ok(void 0);
919
1229
  } catch (error) {
920
- logger2.error("Failed to connect to pgvector", { error: error instanceof Error ? error.message : String(error) });
1230
+ logger3.error("Failed to connect to pgvector", { error: error instanceof Error ? error.message : String(error) });
921
1231
  return err(HaiVecdbError.CONNECTION_FAILED, vecdbM("vecdb_connectionFailed", { params: { error: error instanceof Error ? error.message : String(error) } }), error);
922
1232
  }
923
1233
  },
@@ -928,10 +1238,10 @@ function createPgvectorProvider() {
928
1238
  }
929
1239
  pool = null;
930
1240
  config = null;
931
- logger2.info("pgvector connection closed");
1241
+ logger3.info("pgvector connection closed");
932
1242
  return ok(void 0);
933
1243
  } catch (error) {
934
- logger2.error("Failed to close pgvector connection", { error: error instanceof Error ? error.message : String(error) });
1244
+ logger3.error("Failed to close pgvector connection", { error: error instanceof Error ? error.message : String(error) });
935
1245
  return err(HaiVecdbError.CONNECTION_FAILED, vecdbM("vecdb_closeFailed", { params: { error: String(error) } }), error);
936
1246
  }
937
1247
  },
@@ -954,7 +1264,7 @@ function sanitizeUrl(url) {
954
1264
  return "(invalid url)";
955
1265
  }
956
1266
  }
957
- var logger3 = core.logger.child({ module: "vecdb", scope: "qdrant" });
1267
+ var logger4 = core.logger.child({ module: "vecdb", scope: "qdrant" });
958
1268
  function isQdrantModule(value) {
959
1269
  if (typeof value !== "object" || value === null) {
960
1270
  return false;
@@ -990,13 +1300,13 @@ function createQdrantProvider() {
990
1300
  const mod = await import('@qdrant/js-client-rest');
991
1301
  if (!isQdrantModule(mod)) {
992
1302
  const error = new Error("@qdrant/js-client-rest driver module does not export QdrantClient");
993
- logger3.error("Failed to load Qdrant driver", { error: error.message });
1303
+ logger4.error("Failed to load Qdrant driver", { error: error.message });
994
1304
  return err(HaiVecdbError.DRIVER_NOT_FOUND, vecdbM("vecdb_driverNotFound", { params: { driver: "@qdrant/js-client-rest" } }), error);
995
1305
  }
996
1306
  return ok(mod);
997
1307
  } catch (error) {
998
1308
  if (isMissingModuleError(error, "@qdrant/js-client-rest")) {
999
- logger3.error("Failed to load Qdrant driver", { error: error instanceof Error ? error.message : String(error) });
1309
+ logger4.error("Failed to load Qdrant driver", { error: error instanceof Error ? error.message : String(error) });
1000
1310
  return err(HaiVecdbError.DRIVER_NOT_FOUND, vecdbM("vecdb_driverNotFound", { params: { driver: "@qdrant/js-client-rest" } }), error);
1001
1311
  }
1002
1312
  throw error;
@@ -1038,10 +1348,10 @@ function createQdrantProvider() {
1038
1348
  })
1039
1349
  );
1040
1350
  }
1041
- const ctx = { isConnected: () => client !== null, logger: logger3, operationLog: () => config?.operationLog };
1351
+ const ctx = { isConnected: () => client !== null, logger: logger4, operationLog: () => config?.operationLog };
1042
1352
  const collectionDriver = {
1043
1353
  async create(name, options) {
1044
- logger3.debug("Creating collection", { name, dimension: options.dimension, metric: options.metric });
1354
+ logger4.debug("Creating collection", { name, dimension: options.dimension, metric: options.metric });
1045
1355
  const collections = await client.getCollections();
1046
1356
  const exists = collections.collections.some((c) => c.name === name);
1047
1357
  if (exists) {
@@ -1054,21 +1364,21 @@ function createQdrantProvider() {
1054
1364
  distance: toQdrantDistance(metric)
1055
1365
  }
1056
1366
  });
1057
- logger3.info("Collection created", { name, dimension: options.dimension, metric });
1367
+ logger4.info("Collection created", { name, dimension: options.dimension, metric });
1058
1368
  return ok(void 0);
1059
1369
  },
1060
1370
  async drop(name) {
1061
- logger3.debug("Dropping collection", { name });
1371
+ logger4.debug("Dropping collection", { name });
1062
1372
  const infoResult = await getCollectionInfo(name);
1063
1373
  if (!infoResult.success) {
1064
1374
  return infoResult;
1065
1375
  }
1066
1376
  await client.deleteCollection(name);
1067
- logger3.info("Collection dropped", { name });
1377
+ logger4.info("Collection dropped", { name });
1068
1378
  return ok(void 0);
1069
1379
  },
1070
1380
  async exists(name) {
1071
- logger3.debug("Checking collection exists", { name });
1381
+ logger4.debug("Checking collection exists", { name });
1072
1382
  try {
1073
1383
  await client.getCollection(name);
1074
1384
  return ok(true);
@@ -1080,7 +1390,7 @@ function createQdrantProvider() {
1080
1390
  }
1081
1391
  },
1082
1392
  async info(name) {
1083
- logger3.debug("Getting collection info", { name });
1393
+ logger4.debug("Getting collection info", { name });
1084
1394
  const infoResult = await getCollectionInfo(name);
1085
1395
  if (!infoResult.success) {
1086
1396
  return infoResult;
@@ -1098,7 +1408,7 @@ function createQdrantProvider() {
1098
1408
  });
1099
1409
  },
1100
1410
  async list() {
1101
- logger3.debug("Listing collections");
1411
+ logger4.debug("Listing collections");
1102
1412
  const collections = await client.getCollections();
1103
1413
  const names = collections.collections.map((c) => c.name);
1104
1414
  return ok(names);
@@ -1106,7 +1416,7 @@ function createQdrantProvider() {
1106
1416
  };
1107
1417
  const vectorDriver = {
1108
1418
  async insert(collection, documents) {
1109
- logger3.debug("Inserting vectors", { collection, count: documents.length });
1419
+ logger4.debug("Inserting vectors", { collection, count: documents.length });
1110
1420
  const dimensionResult = await getCollectionDimension(collection);
1111
1421
  if (!dimensionResult.success) {
1112
1422
  return dimensionResult;
@@ -1127,11 +1437,11 @@ function createQdrantProvider() {
1127
1437
  }
1128
1438
  }));
1129
1439
  await client.upsert(collection, { points });
1130
- logger3.info("Vectors inserted", { collection, count: documents.length });
1440
+ logger4.info("Vectors inserted", { collection, count: documents.length });
1131
1441
  return ok(void 0);
1132
1442
  },
1133
1443
  async upsert(collection, documents) {
1134
- logger3.debug("Upserting vectors", { collection, count: documents.length });
1444
+ logger4.debug("Upserting vectors", { collection, count: documents.length });
1135
1445
  const dimensionResult = await getCollectionDimension(collection);
1136
1446
  if (!dimensionResult.success) {
1137
1447
  return dimensionResult;
@@ -1152,20 +1462,20 @@ function createQdrantProvider() {
1152
1462
  }
1153
1463
  }));
1154
1464
  await client.upsert(collection, { points });
1155
- logger3.info("Vectors upserted", { collection, count: documents.length });
1465
+ logger4.info("Vectors upserted", { collection, count: documents.length });
1156
1466
  return ok(void 0);
1157
1467
  },
1158
1468
  async delete(collection, ids) {
1159
- logger3.debug("Deleting vectors", { collection, count: ids.length });
1469
+ logger4.debug("Deleting vectors", { collection, count: ids.length });
1160
1470
  const uuids = ids.map(hashToUuid);
1161
1471
  await client.delete(collection, { points: uuids });
1162
- logger3.info("Vectors deleted", { collection, count: ids.length });
1472
+ logger4.info("Vectors deleted", { collection, count: ids.length });
1163
1473
  return ok(void 0);
1164
1474
  },
1165
1475
  async search(collection, vector, options) {
1166
1476
  const topK = options?.topK ?? 10;
1167
1477
  const minScore = options?.minScore ?? 0;
1168
- logger3.debug("Searching vectors", { collection, topK, hasFilter: !!options?.filter });
1478
+ logger4.debug("Searching vectors", { collection, topK, hasFilter: !!options?.filter });
1169
1479
  const dimensionResult = await getCollectionDimension(collection);
1170
1480
  if (!dimensionResult.success) {
1171
1481
  return dimensionResult;
@@ -1202,7 +1512,7 @@ function createQdrantProvider() {
1202
1512
  return ok(results);
1203
1513
  },
1204
1514
  async count(collection) {
1205
- logger3.debug("Counting vectors", { collection });
1515
+ logger4.debug("Counting vectors", { collection });
1206
1516
  const infoResult = await getCollectionInfo(collection);
1207
1517
  if (!infoResult.success) {
1208
1518
  return infoResult;
@@ -1230,17 +1540,17 @@ function createQdrantProvider() {
1230
1540
  await qdrantClient.getCollections();
1231
1541
  client = qdrantClient;
1232
1542
  config = qdrantConfig;
1233
- logger3.info("Qdrant connected", { url: sanitizeUrl(qdrantConfig.url) });
1543
+ logger4.info("Qdrant connected", { url: sanitizeUrl(qdrantConfig.url) });
1234
1544
  return ok(void 0);
1235
1545
  } catch (error) {
1236
- logger3.error("Failed to connect to Qdrant", { error: error instanceof Error ? error.message : String(error) });
1546
+ logger4.error("Failed to connect to Qdrant", { error: error instanceof Error ? error.message : String(error) });
1237
1547
  return err(HaiVecdbError.CONNECTION_FAILED, vecdbM("vecdb_connectionFailed", { params: { error: String(error) } }), error);
1238
1548
  }
1239
1549
  },
1240
1550
  async close() {
1241
1551
  client = null;
1242
1552
  config = null;
1243
- logger3.info("Qdrant connection closed");
1553
+ logger4.info("Qdrant connection closed");
1244
1554
  return ok(void 0);
1245
1555
  },
1246
1556
  isConnected() {
@@ -1252,7 +1562,7 @@ function createQdrantProvider() {
1252
1562
  }
1253
1563
 
1254
1564
  // src/vecdb-main.ts
1255
- var logger4 = core.logger.child({ module: "vecdb", scope: "main" });
1565
+ var logger5 = core.logger.child({ module: "vecdb", scope: "main" });
1256
1566
  var currentProvider = null;
1257
1567
  var currentConfig = null;
1258
1568
  var initInProgress = false;
@@ -1264,6 +1574,8 @@ function createProvider(config) {
1264
1574
  return createPgvectorProvider();
1265
1575
  case "qdrant":
1266
1576
  return createQdrantProvider();
1577
+ case "chroma":
1578
+ return createChromaProvider();
1267
1579
  }
1268
1580
  }
1269
1581
  var notInitialized = core.module.createNotInitializedKit(
@@ -1281,22 +1593,22 @@ var vecdb = {
1281
1593
  */
1282
1594
  async init(config) {
1283
1595
  if (initInProgress) {
1284
- logger4.warn("Vecdb init already in progress, skipping concurrent call");
1596
+ logger5.warn("Vecdb init already in progress, skipping concurrent call");
1285
1597
  return err(HaiVecdbError.CONFIG_ERROR, vecdbM("vecdb_initInProgress"));
1286
1598
  }
1287
1599
  initInProgress = true;
1288
1600
  try {
1289
1601
  if (currentProvider) {
1290
- logger4.warn("Vecdb module is already initialized, reinitializing");
1602
+ logger5.warn("Vecdb module is already initialized, reinitializing");
1291
1603
  const closeResult = await vecdb.close();
1292
1604
  if (!closeResult.success) {
1293
1605
  return closeResult;
1294
1606
  }
1295
1607
  }
1296
- logger4.info("Initializing vecdb module");
1608
+ logger5.info("Initializing vecdb module");
1297
1609
  const parseResult = VecdbConfigSchema.safeParse(config);
1298
1610
  if (!parseResult.success) {
1299
- logger4.error("Vecdb config validation failed", { error: parseResult.error.message });
1611
+ logger5.error("Vecdb config validation failed", { error: parseResult.error.message });
1300
1612
  return err(HaiVecdbError.CONFIG_ERROR, vecdbM("vecdb_configError", { params: { error: parseResult.error.message } }), parseResult.error);
1301
1613
  }
1302
1614
  const parsed = parseResult.data;
@@ -1304,7 +1616,7 @@ var vecdb = {
1304
1616
  const provider = createProvider(parsed);
1305
1617
  const connectResult = await provider.connect(parsed);
1306
1618
  if (!connectResult.success) {
1307
- logger4.error("Vecdb module initialization failed", {
1619
+ logger5.error("Vecdb module initialization failed", {
1308
1620
  code: connectResult.error.code,
1309
1621
  message: connectResult.error.message
1310
1622
  });
@@ -1312,10 +1624,10 @@ var vecdb = {
1312
1624
  }
1313
1625
  currentProvider = provider;
1314
1626
  currentConfig = parsed;
1315
- logger4.info("Vecdb module initialized", { type: parsed.type });
1627
+ logger5.info("Vecdb module initialized", { type: parsed.type });
1316
1628
  return ok(void 0);
1317
1629
  } catch (error) {
1318
- logger4.error("Vecdb module initialization failed", { error });
1630
+ logger5.error("Vecdb module initialization failed", { error });
1319
1631
  return err(HaiVecdbError.CONNECTION_FAILED, vecdbM("vecdb_initFailed", { params: { error: error instanceof Error ? error.message : String(error) } }), error);
1320
1632
  }
1321
1633
  } finally {
@@ -1342,6 +1654,35 @@ var vecdb = {
1342
1654
  get config() {
1343
1655
  return currentConfig ? core.sanitize.sanitizeSensitiveFields(currentConfig) : null;
1344
1656
  },
1657
+ /** 获取底层后端的原始连接信息(含凭证,未初始化时为 null;仅供同进程内集成使用) */
1658
+ get rawConnection() {
1659
+ if (!currentConfig)
1660
+ return null;
1661
+ if (currentConfig.type === "qdrant")
1662
+ return { type: "qdrant", url: currentConfig.url, apiKey: currentConfig.apiKey };
1663
+ if (currentConfig.type === "pgvector") {
1664
+ return {
1665
+ type: "pgvector",
1666
+ connectionString: currentConfig.url,
1667
+ host: currentConfig.host,
1668
+ port: currentConfig.port,
1669
+ database: currentConfig.database,
1670
+ user: currentConfig.user,
1671
+ password: currentConfig.password
1672
+ };
1673
+ }
1674
+ if (currentConfig.type === "chroma") {
1675
+ return {
1676
+ type: "chroma",
1677
+ url: currentConfig.url,
1678
+ host: currentConfig.host,
1679
+ port: currentConfig.port,
1680
+ apiKey: currentConfig.apiKey,
1681
+ path: currentConfig.path
1682
+ };
1683
+ }
1684
+ return { type: currentConfig.type, path: currentConfig.path };
1685
+ },
1345
1686
  /** 检查是否已初始化 */
1346
1687
  get isInitialized() {
1347
1688
  return currentProvider !== null && currentProvider.isConnected();
@@ -1354,20 +1695,20 @@ var vecdb = {
1354
1695
  async close() {
1355
1696
  if (!currentProvider) {
1356
1697
  currentConfig = null;
1357
- logger4.info("Vecdb module already closed, skipping");
1698
+ logger5.info("Vecdb module already closed, skipping");
1358
1699
  return ok(void 0);
1359
1700
  }
1360
- logger4.info("Closing vecdb module");
1701
+ logger5.info("Closing vecdb module");
1361
1702
  try {
1362
1703
  const closeResult = await currentProvider.close();
1363
1704
  if (!closeResult.success) {
1364
- logger4.error("Vecdb module close failed", { code: closeResult.error.code, message: closeResult.error.message });
1705
+ logger5.error("Vecdb module close failed", { code: closeResult.error.code, message: closeResult.error.message });
1365
1706
  return closeResult;
1366
1707
  }
1367
- logger4.info("Vecdb module closed");
1708
+ logger5.info("Vecdb module closed");
1368
1709
  return ok(void 0);
1369
1710
  } catch (error) {
1370
- logger4.error("Vecdb module close failed", { error });
1711
+ logger5.error("Vecdb module close failed", { error });
1371
1712
  return err(HaiVecdbError.CONNECTION_FAILED, vecdbM("vecdb_closeFailed", { params: { error: error instanceof Error ? error.message : String(error) } }), error);
1372
1713
  } finally {
1373
1714
  currentProvider = null;