@lov3kaizen/agentsea-embeddings 1.0.1 → 1.1.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.
@@ -33,13 +33,21 @@ __export(stores_exports, {
33
33
  BaseStore: () => BaseStore,
34
34
  ChromaStore: () => ChromaStore,
35
35
  MemoryStore: () => MemoryStore,
36
+ MilvusSdkBackend: () => MilvusSdkBackend,
37
+ MilvusStore: () => MilvusStore,
38
+ PgVectorStore: () => PgVectorStore,
36
39
  PineconeStore: () => PineconeStore,
37
40
  QdrantStore: () => QdrantStore,
41
+ WeaviateSdkBackend: () => WeaviateSdkBackend,
42
+ WeaviateStore: () => WeaviateStore,
38
43
  createChromaStore: () => createChromaStore,
39
44
  createMemoryStore: () => createMemoryStore,
45
+ createMilvusStore: () => createMilvusStore,
46
+ createPgVectorStore: () => createPgVectorStore,
40
47
  createPineconeStore: () => createPineconeStore,
41
48
  createQdrantStore: () => createQdrantStore,
42
- createStore: () => createStore
49
+ createStore: () => createStore,
50
+ createWeaviateStore: () => createWeaviateStore
43
51
  });
44
52
  module.exports = __toCommonJS(stores_exports);
45
53
 
@@ -478,6 +486,8 @@ var MemoryStore = class extends BaseStore {
478
486
  }
479
487
  return Promise.resolve({
480
488
  deletedCount,
489
+ requestedCount: ids.length,
490
+ countExact: true,
481
491
  durationMs: performance.now() - startTime
482
492
  });
483
493
  }
@@ -490,6 +500,8 @@ var MemoryStore = class extends BaseStore {
490
500
  this.namespaces.clear();
491
501
  return Promise.resolve({
492
502
  deletedCount: count2,
503
+ requestedCount: count2,
504
+ countExact: true,
493
505
  durationMs: performance.now() - startTime
494
506
  });
495
507
  }
@@ -497,6 +509,8 @@ var MemoryStore = class extends BaseStore {
497
509
  if (!nsIds) {
498
510
  return Promise.resolve({
499
511
  deletedCount: 0,
512
+ requestedCount: 0,
513
+ countExact: true,
500
514
  durationMs: performance.now() - startTime
501
515
  });
502
516
  }
@@ -507,6 +521,8 @@ var MemoryStore = class extends BaseStore {
507
521
  this.namespaces.delete(namespace);
508
522
  return Promise.resolve({
509
523
  deletedCount: count,
524
+ requestedCount: count,
525
+ countExact: true,
510
526
  durationMs: performance.now() - startTime
511
527
  });
512
528
  }
@@ -710,6 +726,8 @@ var PineconeStore = class extends BaseStore {
710
726
  );
711
727
  return {
712
728
  deletedCount: ids.length,
729
+ requestedCount: ids.length,
730
+ countExact: false,
713
731
  durationMs: performance.now() - startTime
714
732
  };
715
733
  }
@@ -717,13 +735,15 @@ var PineconeStore = class extends BaseStore {
717
735
  await this.ensureInitialized();
718
736
  const startTime = performance.now();
719
737
  const namespace = options?.namespace ?? this.namespace;
738
+ const before = await this.getStats().catch(() => void 0);
720
739
  const ns = this.index.namespace(
721
740
  namespace
722
741
  );
723
742
  await ns.deleteAll();
724
743
  return {
725
- deletedCount: -1,
726
- // Unknown count
744
+ deletedCount: before?.vectorCount ?? 0,
745
+ requestedCount: before?.vectorCount,
746
+ countExact: before !== void 0,
727
747
  durationMs: performance.now() - startTime
728
748
  };
729
749
  }
@@ -884,12 +904,15 @@ var ChromaStore = class extends BaseStore {
884
904
  await this.collection.delete({ ids });
885
905
  return {
886
906
  deletedCount: ids.length,
907
+ requestedCount: ids.length,
908
+ countExact: false,
887
909
  durationMs: performance.now() - startTime
888
910
  };
889
911
  }
890
912
  async deleteAll(_options) {
891
913
  await this.ensureInitialized();
892
914
  const startTime = performance.now();
915
+ const before = await this.getStats().catch(() => void 0);
893
916
  await this.client.deleteCollection({ name: this.collectionName });
894
917
  this.collection = await this.client.createCollection({
895
918
  name: this.collectionName,
@@ -898,7 +921,9 @@ var ChromaStore = class extends BaseStore {
898
921
  }
899
922
  });
900
923
  return {
901
- deletedCount: -1,
924
+ deletedCount: before?.vectorCount ?? 0,
925
+ requestedCount: before?.vectorCount,
926
+ countExact: before !== void 0,
902
927
  durationMs: performance.now() - startTime
903
928
  };
904
929
  }
@@ -1088,12 +1113,15 @@ var QdrantStore = class extends BaseStore {
1088
1113
  });
1089
1114
  return {
1090
1115
  deletedCount: ids.length,
1116
+ requestedCount: ids.length,
1117
+ countExact: false,
1091
1118
  durationMs: performance.now() - startTime
1092
1119
  };
1093
1120
  }
1094
1121
  async deleteAll(_options) {
1095
1122
  await this.ensureInitialized();
1096
1123
  const startTime = performance.now();
1124
+ const before = await this.getStats().catch(() => void 0);
1097
1125
  await this.client.deleteCollection(this.collectionName);
1098
1126
  if (this.dimensions) {
1099
1127
  await this.client.createCollection(this.collectionName, {
@@ -1104,7 +1132,9 @@ var QdrantStore = class extends BaseStore {
1104
1132
  });
1105
1133
  }
1106
1134
  return {
1107
- deletedCount: -1,
1135
+ deletedCount: before?.vectorCount ?? 0,
1136
+ requestedCount: before?.vectorCount,
1137
+ countExact: before !== void 0,
1108
1138
  durationMs: performance.now() - startTime
1109
1139
  };
1110
1140
  }
@@ -1148,6 +1178,747 @@ function createQdrantStore(config) {
1148
1178
  return new QdrantStore(config);
1149
1179
  }
1150
1180
 
1181
+ // src/core/optional-import.ts
1182
+ function importOptional(name) {
1183
+ return import(
1184
+ /* @vite-ignore */
1185
+ /* webpackIgnore: true */
1186
+ name
1187
+ );
1188
+ }
1189
+
1190
+ // src/stores/PgVectorStore.ts
1191
+ var PgVectorStore = class extends BaseStore {
1192
+ storeType = "pgvector";
1193
+ pool;
1194
+ injectedPool;
1195
+ table;
1196
+ vectorColumn;
1197
+ contentColumn;
1198
+ metadataColumn;
1199
+ pgConfig;
1200
+ initialized = false;
1201
+ constructor(config) {
1202
+ super(config);
1203
+ if (!config.tableName) {
1204
+ throw new Error("pgvector store requires a `tableName`");
1205
+ }
1206
+ this.pgConfig = config;
1207
+ this.injectedPool = config.pool;
1208
+ this.table = config.tableName;
1209
+ this.vectorColumn = config.vectorColumn ?? "embedding";
1210
+ this.contentColumn = config.contentColumn ?? "content";
1211
+ this.metadataColumn = config.metadataColumn ?? "metadata";
1212
+ }
1213
+ /** The pgvector distance operator for the configured metric. */
1214
+ get distanceOperator() {
1215
+ switch (this.metric) {
1216
+ case "euclidean":
1217
+ return "<->";
1218
+ case "dot_product":
1219
+ return "<#>";
1220
+ case "cosine":
1221
+ default:
1222
+ return "<=>";
1223
+ }
1224
+ }
1225
+ async init() {
1226
+ if (this.initialized) return;
1227
+ if (this.injectedPool) {
1228
+ this.pool = this.injectedPool;
1229
+ } else {
1230
+ let mod;
1231
+ try {
1232
+ mod = await importOptional("pg");
1233
+ } catch {
1234
+ throw new Error(
1235
+ 'pgvector store requires the "pg" package. Install it, or pass a pre-built `pool` to the store.'
1236
+ );
1237
+ }
1238
+ const pg = mod.default ?? mod;
1239
+ const Pool = pg.Pool;
1240
+ this.pool = new Pool(
1241
+ this.pgConfig.connectionString ? { connectionString: this.pgConfig.connectionString } : {
1242
+ host: this.pgConfig.host,
1243
+ port: this.pgConfig.port,
1244
+ database: this.pgConfig.database,
1245
+ user: this.pgConfig.user,
1246
+ password: this.pgConfig.password
1247
+ }
1248
+ );
1249
+ }
1250
+ await this.pool.query("CREATE EXTENSION IF NOT EXISTS vector");
1251
+ const dims = this.dimensions;
1252
+ const vectorType = dims ? `vector(${dims})` : "vector";
1253
+ await this.pool.query(
1254
+ `CREATE TABLE IF NOT EXISTS ${this.ident(this.table)} (
1255
+ id text PRIMARY KEY,
1256
+ ${this.ident(this.contentColumn)} text,
1257
+ ${this.ident(this.metadataColumn)} jsonb,
1258
+ ${this.ident(this.vectorColumn)} ${vectorType}
1259
+ )`
1260
+ );
1261
+ this.initialized = true;
1262
+ }
1263
+ async ensureInitialized() {
1264
+ if (!this.initialized) await this.init();
1265
+ }
1266
+ /** Quote an SQL identifier to guard against injection via config names. */
1267
+ ident(name) {
1268
+ return `"${name.replace(/"/g, '""')}"`;
1269
+ }
1270
+ toVectorLiteral(vector) {
1271
+ return `[${Array.from(vector).join(",")}]`;
1272
+ }
1273
+ async upsert(records, options) {
1274
+ await this.ensureInitialized();
1275
+ const start = performance.now();
1276
+ const batchSize = options?.batchSize ?? 100;
1277
+ const upsertedIds = [];
1278
+ const errors = [];
1279
+ let completed = 0;
1280
+ for (const group of batch(records, batchSize)) {
1281
+ for (const record of group) {
1282
+ try {
1283
+ await this.pool.query(
1284
+ `INSERT INTO ${this.ident(this.table)} (id, ${this.ident(this.contentColumn)}, ${this.ident(this.metadataColumn)}, ${this.ident(this.vectorColumn)})
1285
+ VALUES ($1, $2, $3, $4)
1286
+ ON CONFLICT (id) DO UPDATE SET
1287
+ ${this.ident(this.contentColumn)} = EXCLUDED.${this.ident(this.contentColumn)},
1288
+ ${this.ident(this.metadataColumn)} = EXCLUDED.${this.ident(this.metadataColumn)},
1289
+ ${this.ident(this.vectorColumn)} = EXCLUDED.${this.ident(this.vectorColumn)}`,
1290
+ [
1291
+ record.id,
1292
+ record.text ?? null,
1293
+ JSON.stringify(record.metadata ?? {}),
1294
+ this.toVectorLiteral(record.vector)
1295
+ ]
1296
+ );
1297
+ upsertedIds.push(record.id);
1298
+ } catch (e) {
1299
+ errors.push({ id: record.id, error: e.message });
1300
+ }
1301
+ }
1302
+ completed += group.length;
1303
+ options?.onProgress?.({ completed, total: records.length });
1304
+ }
1305
+ return {
1306
+ upsertedIds,
1307
+ upsertedCount: upsertedIds.length,
1308
+ errors,
1309
+ durationMs: performance.now() - start
1310
+ };
1311
+ }
1312
+ async query(vector, options) {
1313
+ await this.ensureInitialized();
1314
+ const start = performance.now();
1315
+ const topK = options?.topK ?? 10;
1316
+ const params = [this.toVectorLiteral(vector)];
1317
+ let where = "";
1318
+ if (options?.filter && Object.keys(options.filter).length > 0) {
1319
+ params.push(JSON.stringify(options.filter));
1320
+ where = `WHERE ${this.ident(this.metadataColumn)} @> $${params.length}::jsonb`;
1321
+ }
1322
+ params.push(topK);
1323
+ const op = this.distanceOperator;
1324
+ const sql = `SELECT id, ${this.ident(this.contentColumn)} AS content, ${this.ident(this.metadataColumn)} AS metadata, ${this.ident(this.vectorColumn)} ${op} $1 AS distance FROM ${this.ident(this.table)} ${where} ORDER BY ${this.ident(this.vectorColumn)} ${op} $1 ASC LIMIT $${params.length}`;
1325
+ const result = await this.pool.query(sql, params);
1326
+ const matches = result.rows.map((row) => {
1327
+ const distance = Number(row.distance);
1328
+ const score = this.metric === "cosine" ? 1 - distance : 1 / (1 + distance);
1329
+ return {
1330
+ id: String(row.id),
1331
+ text: row.content ?? "",
1332
+ score,
1333
+ distance,
1334
+ metadata: row.metadata ?? {}
1335
+ };
1336
+ }).filter(
1337
+ (m) => options?.minScore === void 0 || m.score >= options.minScore
1338
+ );
1339
+ return {
1340
+ matches,
1341
+ namespace: this.namespace,
1342
+ durationMs: performance.now() - start
1343
+ };
1344
+ }
1345
+ async delete(ids, _options) {
1346
+ await this.ensureInitialized();
1347
+ const start = performance.now();
1348
+ const result = await this.pool.query(
1349
+ `DELETE FROM ${this.ident(this.table)} WHERE id = ANY($1)`,
1350
+ [ids]
1351
+ );
1352
+ const deleted = result.rowCount ?? ids.length;
1353
+ return {
1354
+ deletedCount: deleted,
1355
+ requestedCount: ids.length,
1356
+ countExact: result.rowCount !== null,
1357
+ durationMs: performance.now() - start
1358
+ };
1359
+ }
1360
+ async deleteAll(_options) {
1361
+ await this.ensureInitialized();
1362
+ const start = performance.now();
1363
+ const result = await this.pool.query(
1364
+ `DELETE FROM ${this.ident(this.table)}`
1365
+ );
1366
+ return {
1367
+ deletedCount: result.rowCount ?? 0,
1368
+ requestedCount: result.rowCount ?? void 0,
1369
+ countExact: result.rowCount !== null,
1370
+ durationMs: performance.now() - start
1371
+ };
1372
+ }
1373
+ async getStats() {
1374
+ await this.ensureInitialized();
1375
+ const result = await this.pool.query(
1376
+ `SELECT COUNT(*)::int AS count FROM ${this.ident(this.table)}`
1377
+ );
1378
+ const vectorCount = Number(result.rows[0]?.count ?? 0);
1379
+ return {
1380
+ type: this.storeType,
1381
+ vectorCount,
1382
+ namespaceCount: 1,
1383
+ dimensions: this.dimensions ?? 0,
1384
+ metric: this.metric,
1385
+ lastUpdated: Date.now()
1386
+ };
1387
+ }
1388
+ async checkHealth() {
1389
+ const start = performance.now();
1390
+ try {
1391
+ await this.ensureInitialized();
1392
+ await this.pool.query("SELECT 1");
1393
+ return {
1394
+ healthy: true,
1395
+ latencyMs: performance.now() - start,
1396
+ lastCheck: Date.now()
1397
+ };
1398
+ } catch (e) {
1399
+ return {
1400
+ healthy: false,
1401
+ latencyMs: performance.now() - start,
1402
+ lastCheck: Date.now(),
1403
+ error: e.message
1404
+ };
1405
+ }
1406
+ }
1407
+ async close() {
1408
+ if (this.pool && !this.injectedPool) {
1409
+ await this.pool.end();
1410
+ }
1411
+ this.initialized = false;
1412
+ }
1413
+ };
1414
+ function createPgVectorStore(config) {
1415
+ return new PgVectorStore(config);
1416
+ }
1417
+
1418
+ // src/stores/WeaviateStore.ts
1419
+ var WeaviateStore = class extends BaseStore {
1420
+ storeType = "weaviate";
1421
+ backend;
1422
+ injectedBackend;
1423
+ className;
1424
+ url;
1425
+ apiKey;
1426
+ initialized = false;
1427
+ constructor(config) {
1428
+ super(config);
1429
+ if (!config.url) throw new Error("Weaviate store requires a `url`");
1430
+ if (!config.className) {
1431
+ throw new Error("Weaviate store requires a `className`");
1432
+ }
1433
+ this.url = config.url;
1434
+ this.className = config.className;
1435
+ this.apiKey = config.apiKey;
1436
+ this.injectedBackend = config.backend;
1437
+ }
1438
+ async init() {
1439
+ if (this.initialized) return;
1440
+ this.backend = this.injectedBackend ?? await this.buildSdkBackend();
1441
+ await this.backend.ensureClass(this.className, this.dimensions);
1442
+ this.initialized = true;
1443
+ }
1444
+ async ensureInitialized() {
1445
+ if (!this.initialized) await this.init();
1446
+ }
1447
+ /** Build a {@link WeaviateBackend} backed by the real `weaviate-ts-client`. */
1448
+ async buildSdkBackend() {
1449
+ let mod;
1450
+ try {
1451
+ mod = await importOptional("weaviate-ts-client");
1452
+ } catch {
1453
+ throw new Error(
1454
+ 'Weaviate store requires the "weaviate-ts-client" package. Install it, or pass a custom `backend`.'
1455
+ );
1456
+ }
1457
+ const weaviate = mod.default ?? mod;
1458
+ const u = new URL(this.url);
1459
+ const client = weaviate.client({
1460
+ scheme: u.protocol.replace(":", ""),
1461
+ host: u.host,
1462
+ apiKey: this.apiKey && weaviate.ApiKey ? new weaviate.ApiKey(this.apiKey) : void 0
1463
+ });
1464
+ return new WeaviateSdkBackend(client);
1465
+ }
1466
+ async upsert(records, options) {
1467
+ await this.ensureInitialized();
1468
+ const start = performance.now();
1469
+ const batchSize = options?.batchSize ?? 100;
1470
+ const upsertedIds = [];
1471
+ const errors = [];
1472
+ let completed = 0;
1473
+ for (const group of batch(records, batchSize)) {
1474
+ try {
1475
+ await this.backend.upsert(
1476
+ this.className,
1477
+ group.map((r) => ({
1478
+ id: r.id,
1479
+ vector: Array.from(r.vector),
1480
+ properties: { ...r.metadata ?? {}, text: r.text ?? "" }
1481
+ }))
1482
+ );
1483
+ upsertedIds.push(...group.map((r) => r.id));
1484
+ } catch (e) {
1485
+ for (const r of group)
1486
+ errors.push({ id: r.id, error: e.message });
1487
+ }
1488
+ completed += group.length;
1489
+ options?.onProgress?.({ completed, total: records.length });
1490
+ }
1491
+ return {
1492
+ upsertedIds,
1493
+ upsertedCount: upsertedIds.length,
1494
+ errors,
1495
+ durationMs: performance.now() - start
1496
+ };
1497
+ }
1498
+ async query(vector, options) {
1499
+ await this.ensureInitialized();
1500
+ const start = performance.now();
1501
+ const topK = options?.topK ?? 10;
1502
+ const hits = await this.backend.nearVector(
1503
+ this.className,
1504
+ Array.from(vector),
1505
+ topK,
1506
+ options?.filter
1507
+ );
1508
+ const matches = hits.map((h) => ({
1509
+ id: h.id,
1510
+ text: h.properties.text ?? "",
1511
+ score: h.score,
1512
+ metadata: h.properties
1513
+ })).filter(
1514
+ (m) => options?.minScore === void 0 || m.score >= options.minScore
1515
+ );
1516
+ return {
1517
+ matches,
1518
+ namespace: this.className,
1519
+ durationMs: performance.now() - start
1520
+ };
1521
+ }
1522
+ async delete(ids, _options) {
1523
+ await this.ensureInitialized();
1524
+ const start = performance.now();
1525
+ const deleted = await this.backend.deleteByIds(this.className, ids);
1526
+ return {
1527
+ deletedCount: deleted,
1528
+ requestedCount: ids.length,
1529
+ countExact: true,
1530
+ durationMs: performance.now() - start
1531
+ };
1532
+ }
1533
+ async deleteAll(_options) {
1534
+ await this.ensureInitialized();
1535
+ const start = performance.now();
1536
+ const deleted = await this.backend.deleteAll(this.className);
1537
+ return {
1538
+ deletedCount: deleted,
1539
+ requestedCount: deleted,
1540
+ countExact: true,
1541
+ durationMs: performance.now() - start
1542
+ };
1543
+ }
1544
+ async getStats() {
1545
+ await this.ensureInitialized();
1546
+ return {
1547
+ type: this.storeType,
1548
+ vectorCount: await this.backend.count(this.className),
1549
+ namespaceCount: 1,
1550
+ dimensions: this.dimensions ?? 0,
1551
+ metric: this.metric,
1552
+ lastUpdated: Date.now()
1553
+ };
1554
+ }
1555
+ async checkHealth() {
1556
+ const start = performance.now();
1557
+ try {
1558
+ await this.ensureInitialized();
1559
+ await this.backend.ping();
1560
+ return {
1561
+ healthy: true,
1562
+ latencyMs: performance.now() - start,
1563
+ lastCheck: Date.now()
1564
+ };
1565
+ } catch (e) {
1566
+ return {
1567
+ healthy: false,
1568
+ latencyMs: performance.now() - start,
1569
+ lastCheck: Date.now(),
1570
+ error: e.message
1571
+ };
1572
+ }
1573
+ }
1574
+ close() {
1575
+ this.initialized = false;
1576
+ return Promise.resolve();
1577
+ }
1578
+ };
1579
+ var WeaviateSdkBackend = class {
1580
+ constructor(client) {
1581
+ this.client = client;
1582
+ }
1583
+ async ensureClass(className, _dimensions) {
1584
+ const schema = await this.client.schema.getter().do();
1585
+ if (schema.classes?.some((c) => c.class === className)) return;
1586
+ await this.client.schema.classCreator().withClass({ class: className, vectorizer: "none" }).do();
1587
+ }
1588
+ async upsert(className, objects) {
1589
+ let batcher = this.client.batch.objectsBatcher();
1590
+ for (const o of objects) {
1591
+ batcher = batcher.withObject({
1592
+ class: className,
1593
+ id: o.id,
1594
+ vector: o.vector,
1595
+ properties: o.properties
1596
+ });
1597
+ }
1598
+ await batcher.do();
1599
+ }
1600
+ async nearVector(className, vector, limit, filter) {
1601
+ let q = this.client.graphql.get().withClassName(className).withFields("_additional { id certainty } text").withNearVector({ vector }).withLimit(limit);
1602
+ if (filter) q = q.withWhere(this.toWhere(filter));
1603
+ const res = await q.do();
1604
+ const rows = res.data?.Get?.[className] ?? [];
1605
+ return rows.map((row) => {
1606
+ const additional = row._additional;
1607
+ const { _additional, ...properties } = row;
1608
+ void _additional;
1609
+ return {
1610
+ id: additional.id,
1611
+ score: additional.certainty ?? 0,
1612
+ properties
1613
+ };
1614
+ });
1615
+ }
1616
+ async deleteByIds(className, ids) {
1617
+ let n = 0;
1618
+ for (const id of ids) {
1619
+ await this.client.data.deleter().withClassName(className).withId(id).do();
1620
+ n++;
1621
+ }
1622
+ return n;
1623
+ }
1624
+ async deleteAll(className) {
1625
+ const count = await this.count(className);
1626
+ await this.client.schema.classCreator().withClass({ class: className, vectorizer: "none" }).do().catch(() => void 0);
1627
+ return count;
1628
+ }
1629
+ async count(className) {
1630
+ const res = await this.client.graphql.aggregate().withClassName(className).withFields("meta { count }").do();
1631
+ const agg = res.data?.Aggregate?.[className] ?? [];
1632
+ return agg[0]?.meta?.count ?? 0;
1633
+ }
1634
+ async ping() {
1635
+ await this.client.misc.liveChecker().do();
1636
+ }
1637
+ toWhere(filter) {
1638
+ const operands = Object.entries(filter).map(([path, value]) => ({
1639
+ path: [path],
1640
+ operator: "Equal",
1641
+ ...typeof value === "number" ? { valueNumber: value } : typeof value === "boolean" ? { valueBoolean: value } : { valueText: String(value) }
1642
+ }));
1643
+ return operands.length === 1 ? operands[0] : { operator: "And", operands };
1644
+ }
1645
+ };
1646
+ function createWeaviateStore(config) {
1647
+ return new WeaviateStore(config);
1648
+ }
1649
+
1650
+ // src/stores/MilvusStore.ts
1651
+ var MilvusStore = class extends BaseStore {
1652
+ storeType = "milvus";
1653
+ backend;
1654
+ injectedBackend;
1655
+ collection;
1656
+ milvusConfig;
1657
+ initialized = false;
1658
+ constructor(config) {
1659
+ super(config);
1660
+ if (!config.url) throw new Error("Milvus store requires a `url`");
1661
+ if (!config.collectionName) {
1662
+ throw new Error("Milvus store requires a `collectionName`");
1663
+ }
1664
+ if (!config.dimensions) {
1665
+ throw new Error("Milvus store requires `dimensions`");
1666
+ }
1667
+ this.milvusConfig = config;
1668
+ this.collection = config.collectionName;
1669
+ this.injectedBackend = config.backend;
1670
+ }
1671
+ /** Milvus metric type string for the configured distance metric. */
1672
+ get metricType() {
1673
+ switch (this.metric) {
1674
+ case "euclidean":
1675
+ return "L2";
1676
+ case "dot_product":
1677
+ return "IP";
1678
+ case "cosine":
1679
+ default:
1680
+ return "COSINE";
1681
+ }
1682
+ }
1683
+ async init() {
1684
+ if (this.initialized) return;
1685
+ this.backend = this.injectedBackend ?? await this.buildSdkBackend();
1686
+ await this.backend.ensureCollection(
1687
+ this.collection,
1688
+ this.dimensions,
1689
+ this.metricType
1690
+ );
1691
+ this.initialized = true;
1692
+ }
1693
+ async ensureInitialized() {
1694
+ if (!this.initialized) await this.init();
1695
+ }
1696
+ async buildSdkBackend() {
1697
+ let mod;
1698
+ try {
1699
+ mod = await importOptional("@zilliz/milvus2-sdk-node");
1700
+ } catch {
1701
+ throw new Error(
1702
+ 'Milvus store requires the "@zilliz/milvus2-sdk-node" package. Install it, or pass a custom `backend`.'
1703
+ );
1704
+ }
1705
+ const sdk = mod;
1706
+ const client = new sdk.MilvusClient({
1707
+ address: this.milvusConfig.url,
1708
+ username: this.milvusConfig.username,
1709
+ password: this.milvusConfig.password
1710
+ });
1711
+ return new MilvusSdkBackend(client);
1712
+ }
1713
+ async upsert(records, options) {
1714
+ await this.ensureInitialized();
1715
+ const start = performance.now();
1716
+ const batchSize = options?.batchSize ?? 100;
1717
+ const upsertedIds = [];
1718
+ const errors = [];
1719
+ let completed = 0;
1720
+ for (const group of batch(records, batchSize)) {
1721
+ try {
1722
+ await this.backend.upsert(
1723
+ this.collection,
1724
+ group.map((r) => ({
1725
+ id: r.id,
1726
+ vector: Array.from(r.vector),
1727
+ text: r.text ?? "",
1728
+ metadata: r.metadata ?? {}
1729
+ }))
1730
+ );
1731
+ upsertedIds.push(...group.map((r) => r.id));
1732
+ } catch (e) {
1733
+ for (const r of group)
1734
+ errors.push({ id: r.id, error: e.message });
1735
+ }
1736
+ completed += group.length;
1737
+ options?.onProgress?.({ completed, total: records.length });
1738
+ }
1739
+ return {
1740
+ upsertedIds,
1741
+ upsertedCount: upsertedIds.length,
1742
+ errors,
1743
+ durationMs: performance.now() - start
1744
+ };
1745
+ }
1746
+ async query(vector, options) {
1747
+ await this.ensureInitialized();
1748
+ const start = performance.now();
1749
+ const topK = options?.topK ?? 10;
1750
+ const hits = await this.backend.search(
1751
+ this.collection,
1752
+ Array.from(vector),
1753
+ topK,
1754
+ options?.filter ? this.toExpr(options.filter) : void 0
1755
+ );
1756
+ const matches = hits.map((h) => ({
1757
+ id: h.id,
1758
+ text: h.text,
1759
+ score: h.score,
1760
+ metadata: h.metadata
1761
+ })).filter(
1762
+ (m) => options?.minScore === void 0 || m.score >= options.minScore
1763
+ );
1764
+ return {
1765
+ matches,
1766
+ namespace: this.collection,
1767
+ durationMs: performance.now() - start
1768
+ };
1769
+ }
1770
+ async delete(ids, _options) {
1771
+ await this.ensureInitialized();
1772
+ const start = performance.now();
1773
+ const deleted = await this.backend.deleteByIds(this.collection, ids);
1774
+ return {
1775
+ deletedCount: deleted,
1776
+ requestedCount: ids.length,
1777
+ countExact: true,
1778
+ durationMs: performance.now() - start
1779
+ };
1780
+ }
1781
+ async deleteAll(_options) {
1782
+ await this.ensureInitialized();
1783
+ const start = performance.now();
1784
+ const deleted = await this.backend.deleteAll(this.collection);
1785
+ return {
1786
+ deletedCount: deleted,
1787
+ requestedCount: deleted,
1788
+ countExact: true,
1789
+ durationMs: performance.now() - start
1790
+ };
1791
+ }
1792
+ async getStats() {
1793
+ await this.ensureInitialized();
1794
+ return {
1795
+ type: this.storeType,
1796
+ vectorCount: await this.backend.count(this.collection),
1797
+ namespaceCount: 1,
1798
+ dimensions: this.dimensions ?? 0,
1799
+ metric: this.metric,
1800
+ lastUpdated: Date.now()
1801
+ };
1802
+ }
1803
+ async checkHealth() {
1804
+ const start = performance.now();
1805
+ try {
1806
+ await this.ensureInitialized();
1807
+ await this.backend.ping();
1808
+ return {
1809
+ healthy: true,
1810
+ latencyMs: performance.now() - start,
1811
+ lastCheck: Date.now()
1812
+ };
1813
+ } catch (e) {
1814
+ return {
1815
+ healthy: false,
1816
+ latencyMs: performance.now() - start,
1817
+ lastCheck: Date.now(),
1818
+ error: e.message
1819
+ };
1820
+ }
1821
+ }
1822
+ close() {
1823
+ this.initialized = false;
1824
+ return Promise.resolve();
1825
+ }
1826
+ /** Translate a flat equality filter to a Milvus boolean expression. */
1827
+ toExpr(filter) {
1828
+ return Object.entries(filter).map(
1829
+ ([k, v]) => typeof v === "number" ? `metadata["${k}"] == ${v}` : `metadata["${k}"] == "${String(v)}"`
1830
+ ).join(" && ");
1831
+ }
1832
+ };
1833
+ var MilvusSdkBackend = class {
1834
+ constructor(client) {
1835
+ this.client = client;
1836
+ }
1837
+ async ensureCollection(collection, dimensions, metric) {
1838
+ const has = await this.client.hasCollection({
1839
+ collection_name: collection
1840
+ });
1841
+ if (!has.value) {
1842
+ await this.client.createCollection({
1843
+ collection_name: collection,
1844
+ fields: [
1845
+ {
1846
+ name: "id",
1847
+ data_type: "VarChar",
1848
+ is_primary_key: true,
1849
+ max_length: 512
1850
+ },
1851
+ { name: "vector", data_type: "FloatVector", dim: dimensions },
1852
+ { name: "text", data_type: "VarChar", max_length: 65535 },
1853
+ { name: "metadata", data_type: "JSON" }
1854
+ ]
1855
+ });
1856
+ await this.client.createIndex({
1857
+ collection_name: collection,
1858
+ field_name: "vector",
1859
+ index_type: "HNSW",
1860
+ metric_type: metric,
1861
+ params: { M: 16, efConstruction: 200 }
1862
+ });
1863
+ }
1864
+ await this.client.loadCollectionSync({ collection_name: collection });
1865
+ }
1866
+ async upsert(collection, rows) {
1867
+ await this.client.insert({
1868
+ collection_name: collection,
1869
+ data: rows.map((r) => ({
1870
+ id: r.id,
1871
+ vector: r.vector,
1872
+ text: r.text,
1873
+ metadata: r.metadata
1874
+ }))
1875
+ });
1876
+ }
1877
+ async search(collection, vector, limit, filter) {
1878
+ const res = await this.client.search({
1879
+ collection_name: collection,
1880
+ data: [vector],
1881
+ limit,
1882
+ filter,
1883
+ output_fields: ["text", "metadata"]
1884
+ });
1885
+ return res.results.map((r) => ({
1886
+ id: String(r.id),
1887
+ score: Number(r.score),
1888
+ text: r.text ?? "",
1889
+ metadata: r.metadata ?? {}
1890
+ }));
1891
+ }
1892
+ async deleteByIds(collection, ids) {
1893
+ const list = ids.map((id) => `"${id}"`).join(", ");
1894
+ await this.client.deleteEntities({
1895
+ collection_name: collection,
1896
+ expr: `id in [${list}]`
1897
+ });
1898
+ return ids.length;
1899
+ }
1900
+ async deleteAll(collection) {
1901
+ const count = await this.count(collection);
1902
+ await this.client.deleteEntities({
1903
+ collection_name: collection,
1904
+ expr: 'id != ""'
1905
+ });
1906
+ return count;
1907
+ }
1908
+ async count(collection) {
1909
+ const stats = await this.client.getCollectionStatistics({
1910
+ collection_name: collection
1911
+ });
1912
+ return Number(stats.data?.row_count ?? 0);
1913
+ }
1914
+ async ping() {
1915
+ await this.client.hasCollection({ collection_name: "__ping__" });
1916
+ }
1917
+ };
1918
+ function createMilvusStore(config) {
1919
+ return new MilvusStore(config);
1920
+ }
1921
+
1151
1922
  // src/stores/index.ts
1152
1923
  function createStore(type, config) {
1153
1924
  switch (type) {
@@ -1159,8 +1930,16 @@ function createStore(type, config) {
1159
1930
  return new ChromaStore(config);
1160
1931
  case "qdrant":
1161
1932
  return new QdrantStore(config);
1933
+ case "weaviate":
1934
+ return new WeaviateStore(config);
1935
+ case "milvus":
1936
+ return new MilvusStore(config);
1937
+ case "pgvector":
1938
+ return new PgVectorStore(config);
1162
1939
  default:
1163
- return new MemoryStore(config);
1940
+ throw new Error(
1941
+ `Unknown vector store type "${String(type)}". Supported stores: memory, pinecone, chroma, qdrant, weaviate, milvus, pgvector.`
1942
+ );
1164
1943
  }
1165
1944
  }
1166
1945
  // Annotate the CommonJS export names for ESM import in node:
@@ -1168,11 +1947,19 @@ function createStore(type, config) {
1168
1947
  BaseStore,
1169
1948
  ChromaStore,
1170
1949
  MemoryStore,
1950
+ MilvusSdkBackend,
1951
+ MilvusStore,
1952
+ PgVectorStore,
1171
1953
  PineconeStore,
1172
1954
  QdrantStore,
1955
+ WeaviateSdkBackend,
1956
+ WeaviateStore,
1173
1957
  createChromaStore,
1174
1958
  createMemoryStore,
1959
+ createMilvusStore,
1960
+ createPgVectorStore,
1175
1961
  createPineconeStore,
1176
1962
  createQdrantStore,
1177
- createStore
1963
+ createStore,
1964
+ createWeaviateStore
1178
1965
  });