@lov3kaizen/agentsea-embeddings 1.0.0 → 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.
- package/dist/caching/index.d.mts +1 -1
- package/dist/caching/index.d.ts +1 -1
- package/dist/caching/index.js +7 -1
- package/dist/caching/index.mjs +1 -1
- package/dist/chunk-2TCNSTX3.mjs +12 -0
- package/dist/{chunk-NBHIRTJT.mjs → chunk-5GTQFVEI.mjs} +41 -1
- package/dist/chunk-JHWMXQ56.mjs +1650 -0
- package/dist/{chunk-VPSMDBHH.mjs → chunk-MNJPAUDC.mjs} +7 -1
- package/dist/chunking/index.d.mts +1 -1
- package/dist/chunking/index.d.ts +1 -1
- package/dist/{embedding.types-CCgPVxt1.d.ts → embedding.types-6Qr8Mgij.d.mts} +1 -1
- package/dist/{embedding.types-CCgPVxt1.d.mts → embedding.types-6Qr8Mgij.d.ts} +1 -1
- package/dist/{index-DMaQRn2w.d.mts → index-DBlD17rN.d.mts} +1 -1
- package/dist/{index-DMaQRn2w.d.ts → index-DBlD17rN.d.ts} +1 -1
- package/dist/{index-CeG6God2.d.mts → index-DGzfvyHY.d.mts} +5 -2
- package/dist/{index-DWddsKRi.d.ts → index-_uJcyK8e.d.ts} +5 -2
- package/dist/index.d.mts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +812 -7
- package/dist/index.mjs +15 -14
- package/dist/providers/index.d.mts +2 -2
- package/dist/providers/index.d.ts +2 -2
- package/dist/providers/index.js +47 -1
- package/dist/providers/index.mjs +2 -1
- package/dist/stores/index.d.mts +256 -2
- package/dist/stores/index.d.ts +256 -2
- package/dist/stores/index.js +794 -7
- package/dist/stores/index.mjs +20 -3
- package/package.json +8 -5
- package/dist/chunk-TER262ST.mjs +0 -877
package/dist/index.js
CHANGED
|
@@ -1500,20 +1500,33 @@ function createVoyageProvider(config) {
|
|
|
1500
1500
|
return new VoyageProvider(config);
|
|
1501
1501
|
}
|
|
1502
1502
|
|
|
1503
|
+
// src/core/optional-import.ts
|
|
1504
|
+
function importOptional(name) {
|
|
1505
|
+
return import(
|
|
1506
|
+
/* @vite-ignore */
|
|
1507
|
+
/* webpackIgnore: true */
|
|
1508
|
+
name
|
|
1509
|
+
);
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1503
1512
|
// src/providers/LocalProvider.ts
|
|
1504
1513
|
var LocalProvider = class extends BaseProvider {
|
|
1505
1514
|
modelInfo;
|
|
1506
1515
|
embedFn = null;
|
|
1507
1516
|
normalize;
|
|
1508
1517
|
batchSize;
|
|
1518
|
+
modelPath;
|
|
1519
|
+
/** Lazily-built ONNX extractor (only when loading from `modelPath`). */
|
|
1520
|
+
extractorPromise;
|
|
1509
1521
|
constructor(config) {
|
|
1510
1522
|
super({ ...config, type: "local" });
|
|
1511
1523
|
if (!config.embedFn && !config.modelPath) {
|
|
1512
1524
|
throw new Error(
|
|
1513
|
-
"
|
|
1525
|
+
"`embedFn` or `modelPath` (ONNX) is required for the local provider"
|
|
1514
1526
|
);
|
|
1515
1527
|
}
|
|
1516
1528
|
this.embedFn = config.embedFn ?? null;
|
|
1529
|
+
this.modelPath = config.modelPath;
|
|
1517
1530
|
this.normalize = config.normalize ?? true;
|
|
1518
1531
|
this.batchSize = config.batchSize ?? 32;
|
|
1519
1532
|
this.modelInfo = {
|
|
@@ -1527,10 +1540,43 @@ var LocalProvider = class extends BaseProvider {
|
|
|
1527
1540
|
description: "Local embedding model"
|
|
1528
1541
|
};
|
|
1529
1542
|
}
|
|
1543
|
+
/**
|
|
1544
|
+
* Lazily load the ONNX feature-extraction pipeline from `modelPath` via
|
|
1545
|
+
* Transformers.js and adapt it into a {@link LocalEmbeddingFn}.
|
|
1546
|
+
*/
|
|
1547
|
+
getOnnxEmbedFn() {
|
|
1548
|
+
if (!this.extractorPromise) {
|
|
1549
|
+
this.extractorPromise = (async () => {
|
|
1550
|
+
let mod;
|
|
1551
|
+
try {
|
|
1552
|
+
mod = await importOptional("@xenova/transformers");
|
|
1553
|
+
} catch {
|
|
1554
|
+
throw new Error(
|
|
1555
|
+
'Loading local ONNX models from `modelPath` requires the "@xenova/transformers" package. Install it, or pass an `embedFn`.'
|
|
1556
|
+
);
|
|
1557
|
+
}
|
|
1558
|
+
const transformers = mod;
|
|
1559
|
+
return transformers.pipeline("feature-extraction", this.modelPath);
|
|
1560
|
+
})();
|
|
1561
|
+
}
|
|
1562
|
+
return this.extractorPromise;
|
|
1563
|
+
}
|
|
1530
1564
|
get info() {
|
|
1531
1565
|
return this.modelInfo;
|
|
1532
1566
|
}
|
|
1533
1567
|
async doEmbed(texts, options) {
|
|
1568
|
+
if (!this.embedFn && this.modelPath) {
|
|
1569
|
+
const extractor = await this.getOnnxEmbedFn();
|
|
1570
|
+
this.embedFn = async (input) => {
|
|
1571
|
+
const output = await extractor(input, {
|
|
1572
|
+
pooling: "mean",
|
|
1573
|
+
normalize: false
|
|
1574
|
+
// we normalize below if configured
|
|
1575
|
+
});
|
|
1576
|
+
const list = output.tolist();
|
|
1577
|
+
return Array.isArray(list[0]) ? list : [list];
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1534
1580
|
if (!this.embedFn) {
|
|
1535
1581
|
throw new Error("No embedding function configured");
|
|
1536
1582
|
}
|
|
@@ -3433,7 +3479,13 @@ var SQLiteCache = class extends BaseCache {
|
|
|
3433
3479
|
`);
|
|
3434
3480
|
updateStmt.run(Date.now(), key);
|
|
3435
3481
|
const vectorBuffer = row.vector;
|
|
3436
|
-
const vector = Array.from(
|
|
3482
|
+
const vector = Array.from(
|
|
3483
|
+
new Float32Array(
|
|
3484
|
+
vectorBuffer.buffer,
|
|
3485
|
+
vectorBuffer.byteOffset,
|
|
3486
|
+
vectorBuffer.byteLength / Float32Array.BYTES_PER_ELEMENT
|
|
3487
|
+
)
|
|
3488
|
+
);
|
|
3437
3489
|
return {
|
|
3438
3490
|
key: row.key,
|
|
3439
3491
|
vector,
|
|
@@ -3984,6 +4036,8 @@ var MemoryStore = class extends BaseStore {
|
|
|
3984
4036
|
}
|
|
3985
4037
|
return Promise.resolve({
|
|
3986
4038
|
deletedCount,
|
|
4039
|
+
requestedCount: ids.length,
|
|
4040
|
+
countExact: true,
|
|
3987
4041
|
durationMs: performance.now() - startTime
|
|
3988
4042
|
});
|
|
3989
4043
|
}
|
|
@@ -3996,6 +4050,8 @@ var MemoryStore = class extends BaseStore {
|
|
|
3996
4050
|
this.namespaces.clear();
|
|
3997
4051
|
return Promise.resolve({
|
|
3998
4052
|
deletedCount: count2,
|
|
4053
|
+
requestedCount: count2,
|
|
4054
|
+
countExact: true,
|
|
3999
4055
|
durationMs: performance.now() - startTime
|
|
4000
4056
|
});
|
|
4001
4057
|
}
|
|
@@ -4003,6 +4059,8 @@ var MemoryStore = class extends BaseStore {
|
|
|
4003
4059
|
if (!nsIds) {
|
|
4004
4060
|
return Promise.resolve({
|
|
4005
4061
|
deletedCount: 0,
|
|
4062
|
+
requestedCount: 0,
|
|
4063
|
+
countExact: true,
|
|
4006
4064
|
durationMs: performance.now() - startTime
|
|
4007
4065
|
});
|
|
4008
4066
|
}
|
|
@@ -4013,6 +4071,8 @@ var MemoryStore = class extends BaseStore {
|
|
|
4013
4071
|
this.namespaces.delete(namespace);
|
|
4014
4072
|
return Promise.resolve({
|
|
4015
4073
|
deletedCount: count,
|
|
4074
|
+
requestedCount: count,
|
|
4075
|
+
countExact: true,
|
|
4016
4076
|
durationMs: performance.now() - startTime
|
|
4017
4077
|
});
|
|
4018
4078
|
}
|
|
@@ -4207,6 +4267,8 @@ var PineconeStore = class extends BaseStore {
|
|
|
4207
4267
|
);
|
|
4208
4268
|
return {
|
|
4209
4269
|
deletedCount: ids.length,
|
|
4270
|
+
requestedCount: ids.length,
|
|
4271
|
+
countExact: false,
|
|
4210
4272
|
durationMs: performance.now() - startTime
|
|
4211
4273
|
};
|
|
4212
4274
|
}
|
|
@@ -4214,13 +4276,15 @@ var PineconeStore = class extends BaseStore {
|
|
|
4214
4276
|
await this.ensureInitialized();
|
|
4215
4277
|
const startTime = performance.now();
|
|
4216
4278
|
const namespace = options?.namespace ?? this.namespace;
|
|
4279
|
+
const before = await this.getStats().catch(() => void 0);
|
|
4217
4280
|
const ns = this.index.namespace(
|
|
4218
4281
|
namespace
|
|
4219
4282
|
);
|
|
4220
4283
|
await ns.deleteAll();
|
|
4221
4284
|
return {
|
|
4222
|
-
deletedCount:
|
|
4223
|
-
|
|
4285
|
+
deletedCount: before?.vectorCount ?? 0,
|
|
4286
|
+
requestedCount: before?.vectorCount,
|
|
4287
|
+
countExact: before !== void 0,
|
|
4224
4288
|
durationMs: performance.now() - startTime
|
|
4225
4289
|
};
|
|
4226
4290
|
}
|
|
@@ -4381,12 +4445,15 @@ var ChromaStore = class extends BaseStore {
|
|
|
4381
4445
|
await this.collection.delete({ ids });
|
|
4382
4446
|
return {
|
|
4383
4447
|
deletedCount: ids.length,
|
|
4448
|
+
requestedCount: ids.length,
|
|
4449
|
+
countExact: false,
|
|
4384
4450
|
durationMs: performance.now() - startTime
|
|
4385
4451
|
};
|
|
4386
4452
|
}
|
|
4387
4453
|
async deleteAll(_options) {
|
|
4388
4454
|
await this.ensureInitialized();
|
|
4389
4455
|
const startTime = performance.now();
|
|
4456
|
+
const before = await this.getStats().catch(() => void 0);
|
|
4390
4457
|
await this.client.deleteCollection({ name: this.collectionName });
|
|
4391
4458
|
this.collection = await this.client.createCollection({
|
|
4392
4459
|
name: this.collectionName,
|
|
@@ -4395,7 +4462,9 @@ var ChromaStore = class extends BaseStore {
|
|
|
4395
4462
|
}
|
|
4396
4463
|
});
|
|
4397
4464
|
return {
|
|
4398
|
-
deletedCount:
|
|
4465
|
+
deletedCount: before?.vectorCount ?? 0,
|
|
4466
|
+
requestedCount: before?.vectorCount,
|
|
4467
|
+
countExact: before !== void 0,
|
|
4399
4468
|
durationMs: performance.now() - startTime
|
|
4400
4469
|
};
|
|
4401
4470
|
}
|
|
@@ -4585,12 +4654,15 @@ var QdrantStore = class extends BaseStore {
|
|
|
4585
4654
|
});
|
|
4586
4655
|
return {
|
|
4587
4656
|
deletedCount: ids.length,
|
|
4657
|
+
requestedCount: ids.length,
|
|
4658
|
+
countExact: false,
|
|
4588
4659
|
durationMs: performance.now() - startTime
|
|
4589
4660
|
};
|
|
4590
4661
|
}
|
|
4591
4662
|
async deleteAll(_options) {
|
|
4592
4663
|
await this.ensureInitialized();
|
|
4593
4664
|
const startTime = performance.now();
|
|
4665
|
+
const before = await this.getStats().catch(() => void 0);
|
|
4594
4666
|
await this.client.deleteCollection(this.collectionName);
|
|
4595
4667
|
if (this.dimensions) {
|
|
4596
4668
|
await this.client.createCollection(this.collectionName, {
|
|
@@ -4601,7 +4673,9 @@ var QdrantStore = class extends BaseStore {
|
|
|
4601
4673
|
});
|
|
4602
4674
|
}
|
|
4603
4675
|
return {
|
|
4604
|
-
deletedCount:
|
|
4676
|
+
deletedCount: before?.vectorCount ?? 0,
|
|
4677
|
+
requestedCount: before?.vectorCount,
|
|
4678
|
+
countExact: before !== void 0,
|
|
4605
4679
|
durationMs: performance.now() - startTime
|
|
4606
4680
|
};
|
|
4607
4681
|
}
|
|
@@ -4645,6 +4719,729 @@ function createQdrantStore(config) {
|
|
|
4645
4719
|
return new QdrantStore(config);
|
|
4646
4720
|
}
|
|
4647
4721
|
|
|
4722
|
+
// src/stores/PgVectorStore.ts
|
|
4723
|
+
var PgVectorStore = class extends BaseStore {
|
|
4724
|
+
storeType = "pgvector";
|
|
4725
|
+
pool;
|
|
4726
|
+
injectedPool;
|
|
4727
|
+
table;
|
|
4728
|
+
vectorColumn;
|
|
4729
|
+
contentColumn;
|
|
4730
|
+
metadataColumn;
|
|
4731
|
+
pgConfig;
|
|
4732
|
+
initialized = false;
|
|
4733
|
+
constructor(config) {
|
|
4734
|
+
super(config);
|
|
4735
|
+
if (!config.tableName) {
|
|
4736
|
+
throw new Error("pgvector store requires a `tableName`");
|
|
4737
|
+
}
|
|
4738
|
+
this.pgConfig = config;
|
|
4739
|
+
this.injectedPool = config.pool;
|
|
4740
|
+
this.table = config.tableName;
|
|
4741
|
+
this.vectorColumn = config.vectorColumn ?? "embedding";
|
|
4742
|
+
this.contentColumn = config.contentColumn ?? "content";
|
|
4743
|
+
this.metadataColumn = config.metadataColumn ?? "metadata";
|
|
4744
|
+
}
|
|
4745
|
+
/** The pgvector distance operator for the configured metric. */
|
|
4746
|
+
get distanceOperator() {
|
|
4747
|
+
switch (this.metric) {
|
|
4748
|
+
case "euclidean":
|
|
4749
|
+
return "<->";
|
|
4750
|
+
case "dot_product":
|
|
4751
|
+
return "<#>";
|
|
4752
|
+
case "cosine":
|
|
4753
|
+
default:
|
|
4754
|
+
return "<=>";
|
|
4755
|
+
}
|
|
4756
|
+
}
|
|
4757
|
+
async init() {
|
|
4758
|
+
if (this.initialized) return;
|
|
4759
|
+
if (this.injectedPool) {
|
|
4760
|
+
this.pool = this.injectedPool;
|
|
4761
|
+
} else {
|
|
4762
|
+
let mod;
|
|
4763
|
+
try {
|
|
4764
|
+
mod = await importOptional("pg");
|
|
4765
|
+
} catch {
|
|
4766
|
+
throw new Error(
|
|
4767
|
+
'pgvector store requires the "pg" package. Install it, or pass a pre-built `pool` to the store.'
|
|
4768
|
+
);
|
|
4769
|
+
}
|
|
4770
|
+
const pg = mod.default ?? mod;
|
|
4771
|
+
const Pool = pg.Pool;
|
|
4772
|
+
this.pool = new Pool(
|
|
4773
|
+
this.pgConfig.connectionString ? { connectionString: this.pgConfig.connectionString } : {
|
|
4774
|
+
host: this.pgConfig.host,
|
|
4775
|
+
port: this.pgConfig.port,
|
|
4776
|
+
database: this.pgConfig.database,
|
|
4777
|
+
user: this.pgConfig.user,
|
|
4778
|
+
password: this.pgConfig.password
|
|
4779
|
+
}
|
|
4780
|
+
);
|
|
4781
|
+
}
|
|
4782
|
+
await this.pool.query("CREATE EXTENSION IF NOT EXISTS vector");
|
|
4783
|
+
const dims = this.dimensions;
|
|
4784
|
+
const vectorType = dims ? `vector(${dims})` : "vector";
|
|
4785
|
+
await this.pool.query(
|
|
4786
|
+
`CREATE TABLE IF NOT EXISTS ${this.ident(this.table)} (
|
|
4787
|
+
id text PRIMARY KEY,
|
|
4788
|
+
${this.ident(this.contentColumn)} text,
|
|
4789
|
+
${this.ident(this.metadataColumn)} jsonb,
|
|
4790
|
+
${this.ident(this.vectorColumn)} ${vectorType}
|
|
4791
|
+
)`
|
|
4792
|
+
);
|
|
4793
|
+
this.initialized = true;
|
|
4794
|
+
}
|
|
4795
|
+
async ensureInitialized() {
|
|
4796
|
+
if (!this.initialized) await this.init();
|
|
4797
|
+
}
|
|
4798
|
+
/** Quote an SQL identifier to guard against injection via config names. */
|
|
4799
|
+
ident(name) {
|
|
4800
|
+
return `"${name.replace(/"/g, '""')}"`;
|
|
4801
|
+
}
|
|
4802
|
+
toVectorLiteral(vector) {
|
|
4803
|
+
return `[${Array.from(vector).join(",")}]`;
|
|
4804
|
+
}
|
|
4805
|
+
async upsert(records, options) {
|
|
4806
|
+
await this.ensureInitialized();
|
|
4807
|
+
const start = performance.now();
|
|
4808
|
+
const batchSize = options?.batchSize ?? 100;
|
|
4809
|
+
const upsertedIds = [];
|
|
4810
|
+
const errors = [];
|
|
4811
|
+
let completed = 0;
|
|
4812
|
+
for (const group of batch(records, batchSize)) {
|
|
4813
|
+
for (const record of group) {
|
|
4814
|
+
try {
|
|
4815
|
+
await this.pool.query(
|
|
4816
|
+
`INSERT INTO ${this.ident(this.table)} (id, ${this.ident(this.contentColumn)}, ${this.ident(this.metadataColumn)}, ${this.ident(this.vectorColumn)})
|
|
4817
|
+
VALUES ($1, $2, $3, $4)
|
|
4818
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
4819
|
+
${this.ident(this.contentColumn)} = EXCLUDED.${this.ident(this.contentColumn)},
|
|
4820
|
+
${this.ident(this.metadataColumn)} = EXCLUDED.${this.ident(this.metadataColumn)},
|
|
4821
|
+
${this.ident(this.vectorColumn)} = EXCLUDED.${this.ident(this.vectorColumn)}`,
|
|
4822
|
+
[
|
|
4823
|
+
record.id,
|
|
4824
|
+
record.text ?? null,
|
|
4825
|
+
JSON.stringify(record.metadata ?? {}),
|
|
4826
|
+
this.toVectorLiteral(record.vector)
|
|
4827
|
+
]
|
|
4828
|
+
);
|
|
4829
|
+
upsertedIds.push(record.id);
|
|
4830
|
+
} catch (e) {
|
|
4831
|
+
errors.push({ id: record.id, error: e.message });
|
|
4832
|
+
}
|
|
4833
|
+
}
|
|
4834
|
+
completed += group.length;
|
|
4835
|
+
options?.onProgress?.({ completed, total: records.length });
|
|
4836
|
+
}
|
|
4837
|
+
return {
|
|
4838
|
+
upsertedIds,
|
|
4839
|
+
upsertedCount: upsertedIds.length,
|
|
4840
|
+
errors,
|
|
4841
|
+
durationMs: performance.now() - start
|
|
4842
|
+
};
|
|
4843
|
+
}
|
|
4844
|
+
async query(vector, options) {
|
|
4845
|
+
await this.ensureInitialized();
|
|
4846
|
+
const start = performance.now();
|
|
4847
|
+
const topK = options?.topK ?? 10;
|
|
4848
|
+
const params = [this.toVectorLiteral(vector)];
|
|
4849
|
+
let where = "";
|
|
4850
|
+
if (options?.filter && Object.keys(options.filter).length > 0) {
|
|
4851
|
+
params.push(JSON.stringify(options.filter));
|
|
4852
|
+
where = `WHERE ${this.ident(this.metadataColumn)} @> $${params.length}::jsonb`;
|
|
4853
|
+
}
|
|
4854
|
+
params.push(topK);
|
|
4855
|
+
const op = this.distanceOperator;
|
|
4856
|
+
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}`;
|
|
4857
|
+
const result = await this.pool.query(sql, params);
|
|
4858
|
+
const matches = result.rows.map((row) => {
|
|
4859
|
+
const distance = Number(row.distance);
|
|
4860
|
+
const score = this.metric === "cosine" ? 1 - distance : 1 / (1 + distance);
|
|
4861
|
+
return {
|
|
4862
|
+
id: String(row.id),
|
|
4863
|
+
text: row.content ?? "",
|
|
4864
|
+
score,
|
|
4865
|
+
distance,
|
|
4866
|
+
metadata: row.metadata ?? {}
|
|
4867
|
+
};
|
|
4868
|
+
}).filter(
|
|
4869
|
+
(m) => options?.minScore === void 0 || m.score >= options.minScore
|
|
4870
|
+
);
|
|
4871
|
+
return {
|
|
4872
|
+
matches,
|
|
4873
|
+
namespace: this.namespace,
|
|
4874
|
+
durationMs: performance.now() - start
|
|
4875
|
+
};
|
|
4876
|
+
}
|
|
4877
|
+
async delete(ids, _options) {
|
|
4878
|
+
await this.ensureInitialized();
|
|
4879
|
+
const start = performance.now();
|
|
4880
|
+
const result = await this.pool.query(
|
|
4881
|
+
`DELETE FROM ${this.ident(this.table)} WHERE id = ANY($1)`,
|
|
4882
|
+
[ids]
|
|
4883
|
+
);
|
|
4884
|
+
const deleted = result.rowCount ?? ids.length;
|
|
4885
|
+
return {
|
|
4886
|
+
deletedCount: deleted,
|
|
4887
|
+
requestedCount: ids.length,
|
|
4888
|
+
countExact: result.rowCount !== null,
|
|
4889
|
+
durationMs: performance.now() - start
|
|
4890
|
+
};
|
|
4891
|
+
}
|
|
4892
|
+
async deleteAll(_options) {
|
|
4893
|
+
await this.ensureInitialized();
|
|
4894
|
+
const start = performance.now();
|
|
4895
|
+
const result = await this.pool.query(
|
|
4896
|
+
`DELETE FROM ${this.ident(this.table)}`
|
|
4897
|
+
);
|
|
4898
|
+
return {
|
|
4899
|
+
deletedCount: result.rowCount ?? 0,
|
|
4900
|
+
requestedCount: result.rowCount ?? void 0,
|
|
4901
|
+
countExact: result.rowCount !== null,
|
|
4902
|
+
durationMs: performance.now() - start
|
|
4903
|
+
};
|
|
4904
|
+
}
|
|
4905
|
+
async getStats() {
|
|
4906
|
+
await this.ensureInitialized();
|
|
4907
|
+
const result = await this.pool.query(
|
|
4908
|
+
`SELECT COUNT(*)::int AS count FROM ${this.ident(this.table)}`
|
|
4909
|
+
);
|
|
4910
|
+
const vectorCount = Number(result.rows[0]?.count ?? 0);
|
|
4911
|
+
return {
|
|
4912
|
+
type: this.storeType,
|
|
4913
|
+
vectorCount,
|
|
4914
|
+
namespaceCount: 1,
|
|
4915
|
+
dimensions: this.dimensions ?? 0,
|
|
4916
|
+
metric: this.metric,
|
|
4917
|
+
lastUpdated: Date.now()
|
|
4918
|
+
};
|
|
4919
|
+
}
|
|
4920
|
+
async checkHealth() {
|
|
4921
|
+
const start = performance.now();
|
|
4922
|
+
try {
|
|
4923
|
+
await this.ensureInitialized();
|
|
4924
|
+
await this.pool.query("SELECT 1");
|
|
4925
|
+
return {
|
|
4926
|
+
healthy: true,
|
|
4927
|
+
latencyMs: performance.now() - start,
|
|
4928
|
+
lastCheck: Date.now()
|
|
4929
|
+
};
|
|
4930
|
+
} catch (e) {
|
|
4931
|
+
return {
|
|
4932
|
+
healthy: false,
|
|
4933
|
+
latencyMs: performance.now() - start,
|
|
4934
|
+
lastCheck: Date.now(),
|
|
4935
|
+
error: e.message
|
|
4936
|
+
};
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
async close() {
|
|
4940
|
+
if (this.pool && !this.injectedPool) {
|
|
4941
|
+
await this.pool.end();
|
|
4942
|
+
}
|
|
4943
|
+
this.initialized = false;
|
|
4944
|
+
}
|
|
4945
|
+
};
|
|
4946
|
+
|
|
4947
|
+
// src/stores/WeaviateStore.ts
|
|
4948
|
+
var WeaviateStore = class extends BaseStore {
|
|
4949
|
+
storeType = "weaviate";
|
|
4950
|
+
backend;
|
|
4951
|
+
injectedBackend;
|
|
4952
|
+
className;
|
|
4953
|
+
url;
|
|
4954
|
+
apiKey;
|
|
4955
|
+
initialized = false;
|
|
4956
|
+
constructor(config) {
|
|
4957
|
+
super(config);
|
|
4958
|
+
if (!config.url) throw new Error("Weaviate store requires a `url`");
|
|
4959
|
+
if (!config.className) {
|
|
4960
|
+
throw new Error("Weaviate store requires a `className`");
|
|
4961
|
+
}
|
|
4962
|
+
this.url = config.url;
|
|
4963
|
+
this.className = config.className;
|
|
4964
|
+
this.apiKey = config.apiKey;
|
|
4965
|
+
this.injectedBackend = config.backend;
|
|
4966
|
+
}
|
|
4967
|
+
async init() {
|
|
4968
|
+
if (this.initialized) return;
|
|
4969
|
+
this.backend = this.injectedBackend ?? await this.buildSdkBackend();
|
|
4970
|
+
await this.backend.ensureClass(this.className, this.dimensions);
|
|
4971
|
+
this.initialized = true;
|
|
4972
|
+
}
|
|
4973
|
+
async ensureInitialized() {
|
|
4974
|
+
if (!this.initialized) await this.init();
|
|
4975
|
+
}
|
|
4976
|
+
/** Build a {@link WeaviateBackend} backed by the real `weaviate-ts-client`. */
|
|
4977
|
+
async buildSdkBackend() {
|
|
4978
|
+
let mod;
|
|
4979
|
+
try {
|
|
4980
|
+
mod = await importOptional("weaviate-ts-client");
|
|
4981
|
+
} catch {
|
|
4982
|
+
throw new Error(
|
|
4983
|
+
'Weaviate store requires the "weaviate-ts-client" package. Install it, or pass a custom `backend`.'
|
|
4984
|
+
);
|
|
4985
|
+
}
|
|
4986
|
+
const weaviate = mod.default ?? mod;
|
|
4987
|
+
const u = new URL(this.url);
|
|
4988
|
+
const client = weaviate.client({
|
|
4989
|
+
scheme: u.protocol.replace(":", ""),
|
|
4990
|
+
host: u.host,
|
|
4991
|
+
apiKey: this.apiKey && weaviate.ApiKey ? new weaviate.ApiKey(this.apiKey) : void 0
|
|
4992
|
+
});
|
|
4993
|
+
return new WeaviateSdkBackend(client);
|
|
4994
|
+
}
|
|
4995
|
+
async upsert(records, options) {
|
|
4996
|
+
await this.ensureInitialized();
|
|
4997
|
+
const start = performance.now();
|
|
4998
|
+
const batchSize = options?.batchSize ?? 100;
|
|
4999
|
+
const upsertedIds = [];
|
|
5000
|
+
const errors = [];
|
|
5001
|
+
let completed = 0;
|
|
5002
|
+
for (const group of batch(records, batchSize)) {
|
|
5003
|
+
try {
|
|
5004
|
+
await this.backend.upsert(
|
|
5005
|
+
this.className,
|
|
5006
|
+
group.map((r) => ({
|
|
5007
|
+
id: r.id,
|
|
5008
|
+
vector: Array.from(r.vector),
|
|
5009
|
+
properties: { ...r.metadata ?? {}, text: r.text ?? "" }
|
|
5010
|
+
}))
|
|
5011
|
+
);
|
|
5012
|
+
upsertedIds.push(...group.map((r) => r.id));
|
|
5013
|
+
} catch (e) {
|
|
5014
|
+
for (const r of group)
|
|
5015
|
+
errors.push({ id: r.id, error: e.message });
|
|
5016
|
+
}
|
|
5017
|
+
completed += group.length;
|
|
5018
|
+
options?.onProgress?.({ completed, total: records.length });
|
|
5019
|
+
}
|
|
5020
|
+
return {
|
|
5021
|
+
upsertedIds,
|
|
5022
|
+
upsertedCount: upsertedIds.length,
|
|
5023
|
+
errors,
|
|
5024
|
+
durationMs: performance.now() - start
|
|
5025
|
+
};
|
|
5026
|
+
}
|
|
5027
|
+
async query(vector, options) {
|
|
5028
|
+
await this.ensureInitialized();
|
|
5029
|
+
const start = performance.now();
|
|
5030
|
+
const topK = options?.topK ?? 10;
|
|
5031
|
+
const hits = await this.backend.nearVector(
|
|
5032
|
+
this.className,
|
|
5033
|
+
Array.from(vector),
|
|
5034
|
+
topK,
|
|
5035
|
+
options?.filter
|
|
5036
|
+
);
|
|
5037
|
+
const matches = hits.map((h) => ({
|
|
5038
|
+
id: h.id,
|
|
5039
|
+
text: h.properties.text ?? "",
|
|
5040
|
+
score: h.score,
|
|
5041
|
+
metadata: h.properties
|
|
5042
|
+
})).filter(
|
|
5043
|
+
(m) => options?.minScore === void 0 || m.score >= options.minScore
|
|
5044
|
+
);
|
|
5045
|
+
return {
|
|
5046
|
+
matches,
|
|
5047
|
+
namespace: this.className,
|
|
5048
|
+
durationMs: performance.now() - start
|
|
5049
|
+
};
|
|
5050
|
+
}
|
|
5051
|
+
async delete(ids, _options) {
|
|
5052
|
+
await this.ensureInitialized();
|
|
5053
|
+
const start = performance.now();
|
|
5054
|
+
const deleted = await this.backend.deleteByIds(this.className, ids);
|
|
5055
|
+
return {
|
|
5056
|
+
deletedCount: deleted,
|
|
5057
|
+
requestedCount: ids.length,
|
|
5058
|
+
countExact: true,
|
|
5059
|
+
durationMs: performance.now() - start
|
|
5060
|
+
};
|
|
5061
|
+
}
|
|
5062
|
+
async deleteAll(_options) {
|
|
5063
|
+
await this.ensureInitialized();
|
|
5064
|
+
const start = performance.now();
|
|
5065
|
+
const deleted = await this.backend.deleteAll(this.className);
|
|
5066
|
+
return {
|
|
5067
|
+
deletedCount: deleted,
|
|
5068
|
+
requestedCount: deleted,
|
|
5069
|
+
countExact: true,
|
|
5070
|
+
durationMs: performance.now() - start
|
|
5071
|
+
};
|
|
5072
|
+
}
|
|
5073
|
+
async getStats() {
|
|
5074
|
+
await this.ensureInitialized();
|
|
5075
|
+
return {
|
|
5076
|
+
type: this.storeType,
|
|
5077
|
+
vectorCount: await this.backend.count(this.className),
|
|
5078
|
+
namespaceCount: 1,
|
|
5079
|
+
dimensions: this.dimensions ?? 0,
|
|
5080
|
+
metric: this.metric,
|
|
5081
|
+
lastUpdated: Date.now()
|
|
5082
|
+
};
|
|
5083
|
+
}
|
|
5084
|
+
async checkHealth() {
|
|
5085
|
+
const start = performance.now();
|
|
5086
|
+
try {
|
|
5087
|
+
await this.ensureInitialized();
|
|
5088
|
+
await this.backend.ping();
|
|
5089
|
+
return {
|
|
5090
|
+
healthy: true,
|
|
5091
|
+
latencyMs: performance.now() - start,
|
|
5092
|
+
lastCheck: Date.now()
|
|
5093
|
+
};
|
|
5094
|
+
} catch (e) {
|
|
5095
|
+
return {
|
|
5096
|
+
healthy: false,
|
|
5097
|
+
latencyMs: performance.now() - start,
|
|
5098
|
+
lastCheck: Date.now(),
|
|
5099
|
+
error: e.message
|
|
5100
|
+
};
|
|
5101
|
+
}
|
|
5102
|
+
}
|
|
5103
|
+
close() {
|
|
5104
|
+
this.initialized = false;
|
|
5105
|
+
return Promise.resolve();
|
|
5106
|
+
}
|
|
5107
|
+
};
|
|
5108
|
+
var WeaviateSdkBackend = class {
|
|
5109
|
+
constructor(client) {
|
|
5110
|
+
this.client = client;
|
|
5111
|
+
}
|
|
5112
|
+
async ensureClass(className, _dimensions) {
|
|
5113
|
+
const schema = await this.client.schema.getter().do();
|
|
5114
|
+
if (schema.classes?.some((c) => c.class === className)) return;
|
|
5115
|
+
await this.client.schema.classCreator().withClass({ class: className, vectorizer: "none" }).do();
|
|
5116
|
+
}
|
|
5117
|
+
async upsert(className, objects) {
|
|
5118
|
+
let batcher = this.client.batch.objectsBatcher();
|
|
5119
|
+
for (const o of objects) {
|
|
5120
|
+
batcher = batcher.withObject({
|
|
5121
|
+
class: className,
|
|
5122
|
+
id: o.id,
|
|
5123
|
+
vector: o.vector,
|
|
5124
|
+
properties: o.properties
|
|
5125
|
+
});
|
|
5126
|
+
}
|
|
5127
|
+
await batcher.do();
|
|
5128
|
+
}
|
|
5129
|
+
async nearVector(className, vector, limit, filter) {
|
|
5130
|
+
let q = this.client.graphql.get().withClassName(className).withFields("_additional { id certainty } text").withNearVector({ vector }).withLimit(limit);
|
|
5131
|
+
if (filter) q = q.withWhere(this.toWhere(filter));
|
|
5132
|
+
const res = await q.do();
|
|
5133
|
+
const rows = res.data?.Get?.[className] ?? [];
|
|
5134
|
+
return rows.map((row) => {
|
|
5135
|
+
const additional = row._additional;
|
|
5136
|
+
const { _additional, ...properties } = row;
|
|
5137
|
+
void _additional;
|
|
5138
|
+
return {
|
|
5139
|
+
id: additional.id,
|
|
5140
|
+
score: additional.certainty ?? 0,
|
|
5141
|
+
properties
|
|
5142
|
+
};
|
|
5143
|
+
});
|
|
5144
|
+
}
|
|
5145
|
+
async deleteByIds(className, ids) {
|
|
5146
|
+
let n = 0;
|
|
5147
|
+
for (const id of ids) {
|
|
5148
|
+
await this.client.data.deleter().withClassName(className).withId(id).do();
|
|
5149
|
+
n++;
|
|
5150
|
+
}
|
|
5151
|
+
return n;
|
|
5152
|
+
}
|
|
5153
|
+
async deleteAll(className) {
|
|
5154
|
+
const count = await this.count(className);
|
|
5155
|
+
await this.client.schema.classCreator().withClass({ class: className, vectorizer: "none" }).do().catch(() => void 0);
|
|
5156
|
+
return count;
|
|
5157
|
+
}
|
|
5158
|
+
async count(className) {
|
|
5159
|
+
const res = await this.client.graphql.aggregate().withClassName(className).withFields("meta { count }").do();
|
|
5160
|
+
const agg = res.data?.Aggregate?.[className] ?? [];
|
|
5161
|
+
return agg[0]?.meta?.count ?? 0;
|
|
5162
|
+
}
|
|
5163
|
+
async ping() {
|
|
5164
|
+
await this.client.misc.liveChecker().do();
|
|
5165
|
+
}
|
|
5166
|
+
toWhere(filter) {
|
|
5167
|
+
const operands = Object.entries(filter).map(([path, value]) => ({
|
|
5168
|
+
path: [path],
|
|
5169
|
+
operator: "Equal",
|
|
5170
|
+
...typeof value === "number" ? { valueNumber: value } : typeof value === "boolean" ? { valueBoolean: value } : { valueText: String(value) }
|
|
5171
|
+
}));
|
|
5172
|
+
return operands.length === 1 ? operands[0] : { operator: "And", operands };
|
|
5173
|
+
}
|
|
5174
|
+
};
|
|
5175
|
+
|
|
5176
|
+
// src/stores/MilvusStore.ts
|
|
5177
|
+
var MilvusStore = class extends BaseStore {
|
|
5178
|
+
storeType = "milvus";
|
|
5179
|
+
backend;
|
|
5180
|
+
injectedBackend;
|
|
5181
|
+
collection;
|
|
5182
|
+
milvusConfig;
|
|
5183
|
+
initialized = false;
|
|
5184
|
+
constructor(config) {
|
|
5185
|
+
super(config);
|
|
5186
|
+
if (!config.url) throw new Error("Milvus store requires a `url`");
|
|
5187
|
+
if (!config.collectionName) {
|
|
5188
|
+
throw new Error("Milvus store requires a `collectionName`");
|
|
5189
|
+
}
|
|
5190
|
+
if (!config.dimensions) {
|
|
5191
|
+
throw new Error("Milvus store requires `dimensions`");
|
|
5192
|
+
}
|
|
5193
|
+
this.milvusConfig = config;
|
|
5194
|
+
this.collection = config.collectionName;
|
|
5195
|
+
this.injectedBackend = config.backend;
|
|
5196
|
+
}
|
|
5197
|
+
/** Milvus metric type string for the configured distance metric. */
|
|
5198
|
+
get metricType() {
|
|
5199
|
+
switch (this.metric) {
|
|
5200
|
+
case "euclidean":
|
|
5201
|
+
return "L2";
|
|
5202
|
+
case "dot_product":
|
|
5203
|
+
return "IP";
|
|
5204
|
+
case "cosine":
|
|
5205
|
+
default:
|
|
5206
|
+
return "COSINE";
|
|
5207
|
+
}
|
|
5208
|
+
}
|
|
5209
|
+
async init() {
|
|
5210
|
+
if (this.initialized) return;
|
|
5211
|
+
this.backend = this.injectedBackend ?? await this.buildSdkBackend();
|
|
5212
|
+
await this.backend.ensureCollection(
|
|
5213
|
+
this.collection,
|
|
5214
|
+
this.dimensions,
|
|
5215
|
+
this.metricType
|
|
5216
|
+
);
|
|
5217
|
+
this.initialized = true;
|
|
5218
|
+
}
|
|
5219
|
+
async ensureInitialized() {
|
|
5220
|
+
if (!this.initialized) await this.init();
|
|
5221
|
+
}
|
|
5222
|
+
async buildSdkBackend() {
|
|
5223
|
+
let mod;
|
|
5224
|
+
try {
|
|
5225
|
+
mod = await importOptional("@zilliz/milvus2-sdk-node");
|
|
5226
|
+
} catch {
|
|
5227
|
+
throw new Error(
|
|
5228
|
+
'Milvus store requires the "@zilliz/milvus2-sdk-node" package. Install it, or pass a custom `backend`.'
|
|
5229
|
+
);
|
|
5230
|
+
}
|
|
5231
|
+
const sdk = mod;
|
|
5232
|
+
const client = new sdk.MilvusClient({
|
|
5233
|
+
address: this.milvusConfig.url,
|
|
5234
|
+
username: this.milvusConfig.username,
|
|
5235
|
+
password: this.milvusConfig.password
|
|
5236
|
+
});
|
|
5237
|
+
return new MilvusSdkBackend(client);
|
|
5238
|
+
}
|
|
5239
|
+
async upsert(records, options) {
|
|
5240
|
+
await this.ensureInitialized();
|
|
5241
|
+
const start = performance.now();
|
|
5242
|
+
const batchSize = options?.batchSize ?? 100;
|
|
5243
|
+
const upsertedIds = [];
|
|
5244
|
+
const errors = [];
|
|
5245
|
+
let completed = 0;
|
|
5246
|
+
for (const group of batch(records, batchSize)) {
|
|
5247
|
+
try {
|
|
5248
|
+
await this.backend.upsert(
|
|
5249
|
+
this.collection,
|
|
5250
|
+
group.map((r) => ({
|
|
5251
|
+
id: r.id,
|
|
5252
|
+
vector: Array.from(r.vector),
|
|
5253
|
+
text: r.text ?? "",
|
|
5254
|
+
metadata: r.metadata ?? {}
|
|
5255
|
+
}))
|
|
5256
|
+
);
|
|
5257
|
+
upsertedIds.push(...group.map((r) => r.id));
|
|
5258
|
+
} catch (e) {
|
|
5259
|
+
for (const r of group)
|
|
5260
|
+
errors.push({ id: r.id, error: e.message });
|
|
5261
|
+
}
|
|
5262
|
+
completed += group.length;
|
|
5263
|
+
options?.onProgress?.({ completed, total: records.length });
|
|
5264
|
+
}
|
|
5265
|
+
return {
|
|
5266
|
+
upsertedIds,
|
|
5267
|
+
upsertedCount: upsertedIds.length,
|
|
5268
|
+
errors,
|
|
5269
|
+
durationMs: performance.now() - start
|
|
5270
|
+
};
|
|
5271
|
+
}
|
|
5272
|
+
async query(vector, options) {
|
|
5273
|
+
await this.ensureInitialized();
|
|
5274
|
+
const start = performance.now();
|
|
5275
|
+
const topK = options?.topK ?? 10;
|
|
5276
|
+
const hits = await this.backend.search(
|
|
5277
|
+
this.collection,
|
|
5278
|
+
Array.from(vector),
|
|
5279
|
+
topK,
|
|
5280
|
+
options?.filter ? this.toExpr(options.filter) : void 0
|
|
5281
|
+
);
|
|
5282
|
+
const matches = hits.map((h) => ({
|
|
5283
|
+
id: h.id,
|
|
5284
|
+
text: h.text,
|
|
5285
|
+
score: h.score,
|
|
5286
|
+
metadata: h.metadata
|
|
5287
|
+
})).filter(
|
|
5288
|
+
(m) => options?.minScore === void 0 || m.score >= options.minScore
|
|
5289
|
+
);
|
|
5290
|
+
return {
|
|
5291
|
+
matches,
|
|
5292
|
+
namespace: this.collection,
|
|
5293
|
+
durationMs: performance.now() - start
|
|
5294
|
+
};
|
|
5295
|
+
}
|
|
5296
|
+
async delete(ids, _options) {
|
|
5297
|
+
await this.ensureInitialized();
|
|
5298
|
+
const start = performance.now();
|
|
5299
|
+
const deleted = await this.backend.deleteByIds(this.collection, ids);
|
|
5300
|
+
return {
|
|
5301
|
+
deletedCount: deleted,
|
|
5302
|
+
requestedCount: ids.length,
|
|
5303
|
+
countExact: true,
|
|
5304
|
+
durationMs: performance.now() - start
|
|
5305
|
+
};
|
|
5306
|
+
}
|
|
5307
|
+
async deleteAll(_options) {
|
|
5308
|
+
await this.ensureInitialized();
|
|
5309
|
+
const start = performance.now();
|
|
5310
|
+
const deleted = await this.backend.deleteAll(this.collection);
|
|
5311
|
+
return {
|
|
5312
|
+
deletedCount: deleted,
|
|
5313
|
+
requestedCount: deleted,
|
|
5314
|
+
countExact: true,
|
|
5315
|
+
durationMs: performance.now() - start
|
|
5316
|
+
};
|
|
5317
|
+
}
|
|
5318
|
+
async getStats() {
|
|
5319
|
+
await this.ensureInitialized();
|
|
5320
|
+
return {
|
|
5321
|
+
type: this.storeType,
|
|
5322
|
+
vectorCount: await this.backend.count(this.collection),
|
|
5323
|
+
namespaceCount: 1,
|
|
5324
|
+
dimensions: this.dimensions ?? 0,
|
|
5325
|
+
metric: this.metric,
|
|
5326
|
+
lastUpdated: Date.now()
|
|
5327
|
+
};
|
|
5328
|
+
}
|
|
5329
|
+
async checkHealth() {
|
|
5330
|
+
const start = performance.now();
|
|
5331
|
+
try {
|
|
5332
|
+
await this.ensureInitialized();
|
|
5333
|
+
await this.backend.ping();
|
|
5334
|
+
return {
|
|
5335
|
+
healthy: true,
|
|
5336
|
+
latencyMs: performance.now() - start,
|
|
5337
|
+
lastCheck: Date.now()
|
|
5338
|
+
};
|
|
5339
|
+
} catch (e) {
|
|
5340
|
+
return {
|
|
5341
|
+
healthy: false,
|
|
5342
|
+
latencyMs: performance.now() - start,
|
|
5343
|
+
lastCheck: Date.now(),
|
|
5344
|
+
error: e.message
|
|
5345
|
+
};
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
close() {
|
|
5349
|
+
this.initialized = false;
|
|
5350
|
+
return Promise.resolve();
|
|
5351
|
+
}
|
|
5352
|
+
/** Translate a flat equality filter to a Milvus boolean expression. */
|
|
5353
|
+
toExpr(filter) {
|
|
5354
|
+
return Object.entries(filter).map(
|
|
5355
|
+
([k, v]) => typeof v === "number" ? `metadata["${k}"] == ${v}` : `metadata["${k}"] == "${String(v)}"`
|
|
5356
|
+
).join(" && ");
|
|
5357
|
+
}
|
|
5358
|
+
};
|
|
5359
|
+
var MilvusSdkBackend = class {
|
|
5360
|
+
constructor(client) {
|
|
5361
|
+
this.client = client;
|
|
5362
|
+
}
|
|
5363
|
+
async ensureCollection(collection, dimensions, metric) {
|
|
5364
|
+
const has = await this.client.hasCollection({
|
|
5365
|
+
collection_name: collection
|
|
5366
|
+
});
|
|
5367
|
+
if (!has.value) {
|
|
5368
|
+
await this.client.createCollection({
|
|
5369
|
+
collection_name: collection,
|
|
5370
|
+
fields: [
|
|
5371
|
+
{
|
|
5372
|
+
name: "id",
|
|
5373
|
+
data_type: "VarChar",
|
|
5374
|
+
is_primary_key: true,
|
|
5375
|
+
max_length: 512
|
|
5376
|
+
},
|
|
5377
|
+
{ name: "vector", data_type: "FloatVector", dim: dimensions },
|
|
5378
|
+
{ name: "text", data_type: "VarChar", max_length: 65535 },
|
|
5379
|
+
{ name: "metadata", data_type: "JSON" }
|
|
5380
|
+
]
|
|
5381
|
+
});
|
|
5382
|
+
await this.client.createIndex({
|
|
5383
|
+
collection_name: collection,
|
|
5384
|
+
field_name: "vector",
|
|
5385
|
+
index_type: "HNSW",
|
|
5386
|
+
metric_type: metric,
|
|
5387
|
+
params: { M: 16, efConstruction: 200 }
|
|
5388
|
+
});
|
|
5389
|
+
}
|
|
5390
|
+
await this.client.loadCollectionSync({ collection_name: collection });
|
|
5391
|
+
}
|
|
5392
|
+
async upsert(collection, rows) {
|
|
5393
|
+
await this.client.insert({
|
|
5394
|
+
collection_name: collection,
|
|
5395
|
+
data: rows.map((r) => ({
|
|
5396
|
+
id: r.id,
|
|
5397
|
+
vector: r.vector,
|
|
5398
|
+
text: r.text,
|
|
5399
|
+
metadata: r.metadata
|
|
5400
|
+
}))
|
|
5401
|
+
});
|
|
5402
|
+
}
|
|
5403
|
+
async search(collection, vector, limit, filter) {
|
|
5404
|
+
const res = await this.client.search({
|
|
5405
|
+
collection_name: collection,
|
|
5406
|
+
data: [vector],
|
|
5407
|
+
limit,
|
|
5408
|
+
filter,
|
|
5409
|
+
output_fields: ["text", "metadata"]
|
|
5410
|
+
});
|
|
5411
|
+
return res.results.map((r) => ({
|
|
5412
|
+
id: String(r.id),
|
|
5413
|
+
score: Number(r.score),
|
|
5414
|
+
text: r.text ?? "",
|
|
5415
|
+
metadata: r.metadata ?? {}
|
|
5416
|
+
}));
|
|
5417
|
+
}
|
|
5418
|
+
async deleteByIds(collection, ids) {
|
|
5419
|
+
const list = ids.map((id) => `"${id}"`).join(", ");
|
|
5420
|
+
await this.client.deleteEntities({
|
|
5421
|
+
collection_name: collection,
|
|
5422
|
+
expr: `id in [${list}]`
|
|
5423
|
+
});
|
|
5424
|
+
return ids.length;
|
|
5425
|
+
}
|
|
5426
|
+
async deleteAll(collection) {
|
|
5427
|
+
const count = await this.count(collection);
|
|
5428
|
+
await this.client.deleteEntities({
|
|
5429
|
+
collection_name: collection,
|
|
5430
|
+
expr: 'id != ""'
|
|
5431
|
+
});
|
|
5432
|
+
return count;
|
|
5433
|
+
}
|
|
5434
|
+
async count(collection) {
|
|
5435
|
+
const stats = await this.client.getCollectionStatistics({
|
|
5436
|
+
collection_name: collection
|
|
5437
|
+
});
|
|
5438
|
+
return Number(stats.data?.row_count ?? 0);
|
|
5439
|
+
}
|
|
5440
|
+
async ping() {
|
|
5441
|
+
await this.client.hasCollection({ collection_name: "__ping__" });
|
|
5442
|
+
}
|
|
5443
|
+
};
|
|
5444
|
+
|
|
4648
5445
|
// src/stores/index.ts
|
|
4649
5446
|
function createStore(type, config) {
|
|
4650
5447
|
switch (type) {
|
|
@@ -4656,8 +5453,16 @@ function createStore(type, config) {
|
|
|
4656
5453
|
return new ChromaStore(config);
|
|
4657
5454
|
case "qdrant":
|
|
4658
5455
|
return new QdrantStore(config);
|
|
5456
|
+
case "weaviate":
|
|
5457
|
+
return new WeaviateStore(config);
|
|
5458
|
+
case "milvus":
|
|
5459
|
+
return new MilvusStore(config);
|
|
5460
|
+
case "pgvector":
|
|
5461
|
+
return new PgVectorStore(config);
|
|
4659
5462
|
default:
|
|
4660
|
-
|
|
5463
|
+
throw new Error(
|
|
5464
|
+
`Unknown vector store type "${String(type)}". Supported stores: memory, pinecone, chroma, qdrant, weaviate, milvus, pgvector.`
|
|
5465
|
+
);
|
|
4661
5466
|
}
|
|
4662
5467
|
}
|
|
4663
5468
|
|