mem0ai 3.0.3 → 3.0.5

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.
@@ -4414,6 +4414,108 @@ function escapeFilterKey(key) {
4414
4414
  }
4415
4415
  return key;
4416
4416
  }
4417
+ var OPERATOR_SQL_MAP = {
4418
+ eq: { template: "payload->>'%KEY%' = $%IDX%", numeric: false },
4419
+ ne: { template: "payload->>'%KEY%' != $%IDX%", numeric: false },
4420
+ gt: { template: "(payload->>'%KEY%')::numeric > $%IDX%", numeric: true },
4421
+ gte: { template: "(payload->>'%KEY%')::numeric >= $%IDX%", numeric: true },
4422
+ lt: { template: "(payload->>'%KEY%')::numeric < $%IDX%", numeric: true },
4423
+ lte: { template: "(payload->>'%KEY%')::numeric <= $%IDX%", numeric: true },
4424
+ in: { template: "payload->>'%KEY%' = ANY($%IDX%::text[])", numeric: false },
4425
+ nin: {
4426
+ template: "NOT (payload->>'%KEY%' = ANY($%IDX%::text[]))",
4427
+ numeric: false
4428
+ },
4429
+ contains: {
4430
+ template: "payload->>'%KEY%' LIKE $%IDX% ESCAPE '\\'",
4431
+ numeric: false
4432
+ },
4433
+ icontains: {
4434
+ template: "payload->>'%KEY%' ILIKE $%IDX% ESCAPE '\\'",
4435
+ numeric: false
4436
+ }
4437
+ };
4438
+ function buildFilterConditions(filters, startIndex) {
4439
+ const conditions = [];
4440
+ const values = [];
4441
+ let paramIndex = startIndex;
4442
+ if (!filters) {
4443
+ return { conditions, values, paramIndex };
4444
+ }
4445
+ for (const [key, value] of Object.entries(filters)) {
4446
+ if (key === "$or") {
4447
+ const orGroups = [];
4448
+ for (const orFilter of value) {
4449
+ const sub = buildFilterConditions(orFilter, paramIndex);
4450
+ if (sub.conditions.length > 0) {
4451
+ orGroups.push("(" + sub.conditions.join(" AND ") + ")");
4452
+ values.push(...sub.values);
4453
+ paramIndex = sub.paramIndex;
4454
+ }
4455
+ }
4456
+ if (orGroups.length > 0) {
4457
+ conditions.push("(" + orGroups.join(" OR ") + ")");
4458
+ }
4459
+ continue;
4460
+ }
4461
+ if (key === "$not") {
4462
+ const notGroups = [];
4463
+ for (const notFilter of value) {
4464
+ const sub = buildFilterConditions(notFilter, paramIndex);
4465
+ if (sub.conditions.length > 0) {
4466
+ notGroups.push("(" + sub.conditions.join(" AND ") + ")");
4467
+ values.push(...sub.values);
4468
+ paramIndex = sub.paramIndex;
4469
+ }
4470
+ }
4471
+ if (notGroups.length > 0) {
4472
+ conditions.push("NOT (" + notGroups.join(" OR ") + ")");
4473
+ }
4474
+ continue;
4475
+ }
4476
+ const safeKey = escapeFilterKey(key);
4477
+ if (value === "*") {
4478
+ conditions.push(`payload ? $${paramIndex}`);
4479
+ values.push(key);
4480
+ paramIndex++;
4481
+ continue;
4482
+ }
4483
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
4484
+ for (const [op, opValue] of Object.entries(value)) {
4485
+ const mapping = OPERATOR_SQL_MAP[op];
4486
+ if (!mapping) {
4487
+ throw new Error(`Unsupported filter operator: ${op}`);
4488
+ }
4489
+ const clause = mapping.template.replace("%KEY%", safeKey).replace("%IDX%", String(paramIndex));
4490
+ conditions.push(clause);
4491
+ if (op === "in" || op === "nin") {
4492
+ values.push(opValue.map(String));
4493
+ } else if (op === "contains" || op === "icontains") {
4494
+ const escaped = String(opValue).replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
4495
+ values.push(`%${escaped}%`);
4496
+ } else if (mapping.numeric) {
4497
+ values.push(Number(opValue));
4498
+ } else {
4499
+ values.push(String(opValue));
4500
+ }
4501
+ paramIndex++;
4502
+ }
4503
+ } else if (Array.isArray(value)) {
4504
+ conditions.push(`payload->>'${safeKey}' = ANY($${paramIndex}::text[])`);
4505
+ values.push(value.map(String));
4506
+ paramIndex++;
4507
+ } else {
4508
+ conditions.push(`payload->>'${safeKey}' = $${paramIndex}`);
4509
+ if (typeof value === "boolean") {
4510
+ values.push(JSON.stringify(value));
4511
+ } else {
4512
+ values.push(String(value));
4513
+ }
4514
+ paramIndex++;
4515
+ }
4516
+ }
4517
+ return { conditions, values, paramIndex };
4518
+ }
4417
4519
  var PGVector = class {
4418
4520
  constructor(config) {
4419
4521
  this.collectionName = validateIdentifier(
@@ -4539,18 +4641,13 @@ var PGVector = class {
4539
4641
  }
4540
4642
  async keywordSearch(query, topK = 5, filters) {
4541
4643
  try {
4542
- const filterConditions = [];
4543
- const filterValues = [query, topK];
4544
- let filterIndex = 3;
4545
- if (filters) {
4546
- for (const [key, value] of Object.entries(filters)) {
4547
- const safeKey = escapeFilterKey(key);
4548
- filterConditions.push(`payload->>'${safeKey}' = $${filterIndex}`);
4549
- filterValues.push(value);
4550
- filterIndex++;
4551
- }
4552
- }
4553
- const filterClause = filterConditions.length > 0 ? "AND " + filterConditions.join(" AND ") : "";
4644
+ const {
4645
+ conditions,
4646
+ values,
4647
+ paramIndex: _
4648
+ } = buildFilterConditions(filters, 3);
4649
+ const filterValues = [query, topK, ...values];
4650
+ const filterClause = conditions.length > 0 ? "AND " + conditions.join(" AND ") : "";
4554
4651
  const searchQuery = `
4555
4652
  SELECT id, ts_rank_cd(to_tsvector('simple', payload->>'textLemmatized'), plainto_tsquery('simple', $1)) AS score, payload
4556
4653
  FROM ${this.col()}
@@ -4571,19 +4668,14 @@ var PGVector = class {
4571
4668
  }
4572
4669
  }
4573
4670
  async search(query, topK = 5, filters) {
4574
- const filterConditions = [];
4575
4671
  const queryVector = `[${query.join(",")}]`;
4576
- const filterValues = [queryVector, topK];
4577
- let filterIndex = 3;
4578
- if (filters) {
4579
- for (const [key, value] of Object.entries(filters)) {
4580
- const safeKey = escapeFilterKey(key);
4581
- filterConditions.push(`payload->>'${safeKey}' = $${filterIndex}`);
4582
- filterValues.push(value);
4583
- filterIndex++;
4584
- }
4585
- }
4586
- const filterClause = filterConditions.length > 0 ? "WHERE " + filterConditions.join(" AND ") : "";
4672
+ const {
4673
+ conditions,
4674
+ values,
4675
+ paramIndex: _
4676
+ } = buildFilterConditions(filters, 3);
4677
+ const filterValues = [queryVector, topK, ...values];
4678
+ const filterClause = conditions.length > 0 ? "WHERE " + conditions.join(" AND ") : "";
4587
4679
  const searchQuery = `
4588
4680
  SELECT id, vector <=> $1::vector AS distance, payload
4589
4681
  FROM ${this.col()}
@@ -4637,18 +4729,12 @@ var PGVector = class {
4637
4729
  return result.rows.map((row) => row.table_name);
4638
4730
  }
4639
4731
  async list(filters, topK = 100) {
4640
- const filterConditions = [];
4641
- const filterValues = [];
4642
- let paramIndex = 1;
4643
- if (filters) {
4644
- for (const [key, value] of Object.entries(filters)) {
4645
- const safeKey = escapeFilterKey(key);
4646
- filterConditions.push(`payload->>'${safeKey}' = $${paramIndex}`);
4647
- filterValues.push(value);
4648
- paramIndex++;
4649
- }
4650
- }
4651
- const filterClause = filterConditions.length > 0 ? "WHERE " + filterConditions.join(" AND ") : "";
4732
+ const {
4733
+ conditions,
4734
+ values: filterValues,
4735
+ paramIndex
4736
+ } = buildFilterConditions(filters, 1);
4737
+ const filterClause = conditions.length > 0 ? "WHERE " + conditions.join(" AND ") : "";
4652
4738
  const listQuery = `
4653
4739
  SELECT id, payload
4654
4740
  FROM ${this.col()}
@@ -4660,11 +4746,10 @@ var PGVector = class {
4660
4746
  FROM ${this.col()}
4661
4747
  ${filterClause}
4662
4748
  `;
4663
- filterValues.push(topK);
4749
+ const listValues = [...filterValues, topK];
4664
4750
  const [listResult, countResult] = await Promise.all([
4665
- this.client.query(listQuery, filterValues),
4666
- this.client.query(countQuery, filterValues.slice(0, -1))
4667
- // Remove limit parameter for count query
4751
+ this.client.query(listQuery, listValues),
4752
+ this.client.query(countQuery, filterValues)
4668
4753
  ]);
4669
4754
  const results = listResult.rows.map((row) => ({
4670
4755
  id: row.id,
@@ -4988,7 +5073,7 @@ var parse_vision_messages = async (messages) => {
4988
5073
  };
4989
5074
 
4990
5075
  // src/oss/src/utils/telemetry.ts
4991
- var version = true ? "3.0.3" : "dev";
5076
+ var version = true ? "3.0.5" : "dev";
4992
5077
  var MEM0_TELEMETRY = true;
4993
5078
  var _a;
4994
5079
  try {
@@ -7256,6 +7341,7 @@ export {
7256
7341
  RedisDB,
7257
7342
  SupabaseDB,
7258
7343
  VectorStoreFactory,
7259
- VectorizeDB
7344
+ VectorizeDB,
7345
+ buildFilterConditions
7260
7346
  };
7261
7347
  //# sourceMappingURL=index.mjs.map