mem0ai 3.0.2 → 3.0.3

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.
@@ -836,9 +836,9 @@ var _MemoryVectorStore = class _MemoryVectorStore {
836
836
  if (row) {
837
837
  return row.user_id;
838
838
  }
839
- const randomUserId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
840
- this.db.prepare(`INSERT INTO memory_migrations (user_id) VALUES (?)`).run(randomUserId);
841
- return randomUserId;
839
+ const randomUserId2 = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
840
+ this.db.prepare(`INSERT INTO memory_migrations (user_id) VALUES (?)`).run(randomUserId2);
841
+ return randomUserId2;
842
842
  }
843
843
  async setUserId(userId) {
844
844
  this.db.prepare(`DELETE FROM memory_migrations`).run();
@@ -1125,17 +1125,17 @@ var Qdrant = class {
1125
1125
  if (result.points.length > 0) {
1126
1126
  return (_a2 = result.points[0].payload) == null ? void 0 : _a2.user_id;
1127
1127
  }
1128
- const randomUserId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
1128
+ const randomUserId2 = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
1129
1129
  await this.client.upsert("memory_migrations", {
1130
1130
  points: [
1131
1131
  {
1132
1132
  id: this.generateUUID(),
1133
1133
  vector: [0],
1134
- payload: { user_id: randomUserId }
1134
+ payload: { user_id: randomUserId2 }
1135
1135
  }
1136
1136
  ]
1137
1137
  });
1138
- return randomUserId;
1138
+ return randomUserId2;
1139
1139
  } catch (error) {
1140
1140
  console.error("Error getting user ID:", error);
1141
1141
  throw error;
@@ -1439,11 +1439,11 @@ var VectorizeDB = class {
1439
1439
  if (result.matches.length > 0) {
1440
1440
  return result.matches[0].metadata.userId;
1441
1441
  }
1442
- const randomUserId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
1442
+ const randomUserId2 = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
1443
1443
  const data = {
1444
1444
  id: this.generateUUID(),
1445
1445
  values: [0],
1446
- metadata: { userId: randomUserId }
1446
+ metadata: { userId: randomUserId2 }
1447
1447
  };
1448
1448
  await fetch(
1449
1449
  `https://api.cloudflare.com/client/v4/accounts/${this.accountId}/vectorize/v2/indexes/memory_migrations/upsert`,
@@ -1457,7 +1457,7 @@ var VectorizeDB = class {
1457
1457
  // ndjson format
1458
1458
  }
1459
1459
  );
1460
- return randomUserId;
1460
+ return randomUserId2;
1461
1461
  } catch (error) {
1462
1462
  console.error("Error getting user ID:", error);
1463
1463
  throw new Error(
@@ -2072,9 +2072,9 @@ var RedisDB = class {
2072
2072
  if (userId) {
2073
2073
  return userId;
2074
2074
  }
2075
- const randomUserId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
2076
- await this.client.set("memory_migrations:1", randomUserId);
2077
- return randomUserId;
2075
+ const randomUserId2 = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
2076
+ await this.client.set("memory_migrations:1", randomUserId2);
2077
+ return randomUserId2;
2078
2078
  } catch (error) {
2079
2079
  console.error("Error getting user ID:", error);
2080
2080
  throw error;
@@ -2450,18 +2450,18 @@ See the SQL migration instructions in the code comments.`
2450
2450
  try {
2451
2451
  const { data: tableExists } = await this.client.from("memory_migrations").select("user_id").limit(1);
2452
2452
  if (!tableExists || tableExists.length === 0) {
2453
- const randomUserId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
2454
- const { error: insertError } = await this.client.from("memory_migrations").insert({ user_id: randomUserId });
2453
+ const randomUserId2 = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
2454
+ const { error: insertError } = await this.client.from("memory_migrations").insert({ user_id: randomUserId2 });
2455
2455
  if (insertError) throw insertError;
2456
- return randomUserId;
2456
+ return randomUserId2;
2457
2457
  }
2458
2458
  const { data, error } = await this.client.from("memory_migrations").select("user_id").limit(1);
2459
2459
  if (error) throw error;
2460
2460
  if (!data || data.length === 0) {
2461
- const randomUserId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
2462
- const { error: insertError } = await this.client.from("memory_migrations").insert({ user_id: randomUserId });
2461
+ const randomUserId2 = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
2462
+ const { error: insertError } = await this.client.from("memory_migrations").insert({ user_id: randomUserId2 });
2463
2463
  if (insertError) throw insertError;
2464
- return randomUserId;
2464
+ return randomUserId2;
2465
2465
  }
2466
2466
  return data[0].user_id;
2467
2467
  } catch (error) {
@@ -4341,14 +4341,14 @@ var AzureAISearch = class {
4341
4341
  return userId;
4342
4342
  }
4343
4343
  }
4344
- const randomUserId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
4344
+ const randomUserId2 = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
4345
4345
  await this.searchClient.uploadDocuments([
4346
4346
  {
4347
4347
  id: this.generateUUID(),
4348
- user_id: randomUserId
4348
+ user_id: randomUserId2
4349
4349
  }
4350
4350
  ]);
4351
- return randomUserId;
4351
+ return randomUserId2;
4352
4352
  } catch (error) {
4353
4353
  console.error("Error getting user ID:", error);
4354
4354
  throw error;
@@ -4396,13 +4396,33 @@ var AzureAISearch = class {
4396
4396
 
4397
4397
  // src/oss/src/vector_stores/pgvector.ts
4398
4398
  import pkg from "pg";
4399
- var { Client } = pkg;
4399
+ var { Client, escapeIdentifier } = pkg;
4400
+ var SAFE_IDENTIFIER_RE = /^[a-zA-Z_][a-zA-Z0-9_]{0,127}$/;
4401
+ function validateIdentifier(name, label = "identifier") {
4402
+ if (!SAFE_IDENTIFIER_RE.test(name)) {
4403
+ throw new Error(
4404
+ `Invalid ${label} '${name}': only letters, digits, and underscores are allowed, must start with a letter or underscore, and be at most 128 characters.`
4405
+ );
4406
+ }
4407
+ return name;
4408
+ }
4409
+ function escapeFilterKey(key) {
4410
+ if (!SAFE_IDENTIFIER_RE.test(key)) {
4411
+ throw new Error(
4412
+ `Invalid filter key '${key}': only letters, digits, and underscores are allowed.`
4413
+ );
4414
+ }
4415
+ return key;
4416
+ }
4400
4417
  var PGVector = class {
4401
4418
  constructor(config) {
4402
- this.collectionName = config.collectionName || "memories";
4419
+ this.collectionName = validateIdentifier(
4420
+ config.collectionName || "memories",
4421
+ "collectionName"
4422
+ );
4403
4423
  this.useDiskann = config.diskann || false;
4404
4424
  this.useHnsw = config.hnsw || false;
4405
- this.dbName = config.dbname || "vector_store";
4425
+ this.dbName = validateIdentifier(config.dbname || "vector_store", "dbname");
4406
4426
  this.config = config;
4407
4427
  this.client = new Client({
4408
4428
  database: "postgres",
@@ -4414,6 +4434,9 @@ var PGVector = class {
4414
4434
  });
4415
4435
  this.initialize().catch(console.error);
4416
4436
  }
4437
+ col() {
4438
+ return escapeIdentifier(this.collectionName);
4439
+ }
4417
4440
  async initialize() {
4418
4441
  if (!this._initPromise) {
4419
4442
  this._initPromise = this._doInitialize();
@@ -4460,13 +4483,14 @@ var PGVector = class {
4460
4483
  return result.rows.length > 0;
4461
4484
  }
4462
4485
  async createDatabase(dbName) {
4463
- await this.client.query(`CREATE DATABASE ${dbName}`);
4486
+ await this.client.query(`CREATE DATABASE ${escapeIdentifier(dbName)}`);
4464
4487
  }
4465
4488
  async createCol(embeddingModelDims) {
4489
+ const dims = Math.floor(embeddingModelDims);
4466
4490
  await this.client.query(`
4467
- CREATE TABLE IF NOT EXISTS ${this.collectionName} (
4491
+ CREATE TABLE IF NOT EXISTS ${this.col()} (
4468
4492
  id UUID PRIMARY KEY,
4469
- vector vector(${embeddingModelDims}),
4493
+ vector vector(${dims}),
4470
4494
  payload JSONB
4471
4495
  );
4472
4496
  `);
@@ -4477,8 +4501,8 @@ var PGVector = class {
4477
4501
  );
4478
4502
  if (result.rows.length > 0) {
4479
4503
  await this.client.query(`
4480
- CREATE INDEX IF NOT EXISTS ${this.collectionName}_diskann_idx
4481
- ON ${this.collectionName}
4504
+ CREATE INDEX IF NOT EXISTS ${escapeIdentifier(this.collectionName + "_diskann_idx")}
4505
+ ON ${this.col()}
4482
4506
  USING diskann (vector);
4483
4507
  `);
4484
4508
  }
@@ -4488,8 +4512,8 @@ var PGVector = class {
4488
4512
  } else if (this.useHnsw) {
4489
4513
  try {
4490
4514
  await this.client.query(`
4491
- CREATE INDEX IF NOT EXISTS ${this.collectionName}_hnsw_idx
4492
- ON ${this.collectionName}
4515
+ CREATE INDEX IF NOT EXISTS ${escapeIdentifier(this.collectionName + "_hnsw_idx")}
4516
+ ON ${this.col()}
4493
4517
  USING hnsw (vector vector_cosine_ops);
4494
4518
  `);
4495
4519
  } catch (error) {
@@ -4501,11 +4525,10 @@ var PGVector = class {
4501
4525
  const values = vectors.map((vector, i) => ({
4502
4526
  id: ids[i],
4503
4527
  vector: `[${vector.join(",")}]`,
4504
- // Format vector as string with square brackets
4505
4528
  payload: payloads[i]
4506
4529
  }));
4507
4530
  const query = `
4508
- INSERT INTO ${this.collectionName} (id, vector, payload)
4531
+ INSERT INTO ${this.col()} (id, vector, payload)
4509
4532
  VALUES ($1, $2::vector, $3::jsonb)
4510
4533
  `;
4511
4534
  await Promise.all(
@@ -4521,7 +4544,8 @@ var PGVector = class {
4521
4544
  let filterIndex = 3;
4522
4545
  if (filters) {
4523
4546
  for (const [key, value] of Object.entries(filters)) {
4524
- filterConditions.push(`payload->>'${key}' = $${filterIndex}`);
4547
+ const safeKey = escapeFilterKey(key);
4548
+ filterConditions.push(`payload->>'${safeKey}' = $${filterIndex}`);
4525
4549
  filterValues.push(value);
4526
4550
  filterIndex++;
4527
4551
  }
@@ -4529,7 +4553,7 @@ var PGVector = class {
4529
4553
  const filterClause = filterConditions.length > 0 ? "AND " + filterConditions.join(" AND ") : "";
4530
4554
  const searchQuery = `
4531
4555
  SELECT id, ts_rank_cd(to_tsvector('simple', payload->>'textLemmatized'), plainto_tsquery('simple', $1)) AS score, payload
4532
- FROM ${this.collectionName}
4556
+ FROM ${this.col()}
4533
4557
  WHERE to_tsvector('simple', payload->>'textLemmatized') @@ plainto_tsquery('simple', $1)
4534
4558
  ${filterClause}
4535
4559
  ORDER BY score DESC
@@ -4553,7 +4577,8 @@ var PGVector = class {
4553
4577
  let filterIndex = 3;
4554
4578
  if (filters) {
4555
4579
  for (const [key, value] of Object.entries(filters)) {
4556
- filterConditions.push(`payload->>'${key}' = $${filterIndex}`);
4580
+ const safeKey = escapeFilterKey(key);
4581
+ filterConditions.push(`payload->>'${safeKey}' = $${filterIndex}`);
4557
4582
  filterValues.push(value);
4558
4583
  filterIndex++;
4559
4584
  }
@@ -4561,7 +4586,7 @@ var PGVector = class {
4561
4586
  const filterClause = filterConditions.length > 0 ? "WHERE " + filterConditions.join(" AND ") : "";
4562
4587
  const searchQuery = `
4563
4588
  SELECT id, vector <=> $1::vector AS distance, payload
4564
- FROM ${this.collectionName}
4589
+ FROM ${this.col()}
4565
4590
  ${filterClause}
4566
4591
  ORDER BY distance
4567
4592
  LIMIT $2
@@ -4570,12 +4595,12 @@ var PGVector = class {
4570
4595
  return result.rows.map((row) => ({
4571
4596
  id: row.id,
4572
4597
  payload: row.payload,
4573
- score: row.distance
4598
+ score: Math.max(0, Math.min(1, 1 - Number(row.distance)))
4574
4599
  }));
4575
4600
  }
4576
4601
  async get(vectorId) {
4577
4602
  const result = await this.client.query(
4578
- `SELECT id, payload FROM ${this.collectionName} WHERE id = $1`,
4603
+ `SELECT id, payload FROM ${this.col()} WHERE id = $1`,
4579
4604
  [vectorId]
4580
4605
  );
4581
4606
  if (result.rows.length === 0) return null;
@@ -4588,7 +4613,7 @@ var PGVector = class {
4588
4613
  const vectorStr = `[${vector.join(",")}]`;
4589
4614
  await this.client.query(
4590
4615
  `
4591
- UPDATE ${this.collectionName}
4616
+ UPDATE ${this.col()}
4592
4617
  SET vector = $1::vector, payload = $2::jsonb
4593
4618
  WHERE id = $3
4594
4619
  `,
@@ -4596,13 +4621,12 @@ var PGVector = class {
4596
4621
  );
4597
4622
  }
4598
4623
  async delete(vectorId) {
4599
- await this.client.query(
4600
- `DELETE FROM ${this.collectionName} WHERE id = $1`,
4601
- [vectorId]
4602
- );
4624
+ await this.client.query(`DELETE FROM ${this.col()} WHERE id = $1`, [
4625
+ vectorId
4626
+ ]);
4603
4627
  }
4604
4628
  async deleteCol() {
4605
- await this.client.query(`DROP TABLE IF EXISTS ${this.collectionName}`);
4629
+ await this.client.query(`DROP TABLE IF EXISTS ${this.col()}`);
4606
4630
  }
4607
4631
  async listCols() {
4608
4632
  const result = await this.client.query(`
@@ -4618,7 +4642,8 @@ var PGVector = class {
4618
4642
  let paramIndex = 1;
4619
4643
  if (filters) {
4620
4644
  for (const [key, value] of Object.entries(filters)) {
4621
- filterConditions.push(`payload->>'${key}' = $${paramIndex}`);
4645
+ const safeKey = escapeFilterKey(key);
4646
+ filterConditions.push(`payload->>'${safeKey}' = $${paramIndex}`);
4622
4647
  filterValues.push(value);
4623
4648
  paramIndex++;
4624
4649
  }
@@ -4626,13 +4651,13 @@ var PGVector = class {
4626
4651
  const filterClause = filterConditions.length > 0 ? "WHERE " + filterConditions.join(" AND ") : "";
4627
4652
  const listQuery = `
4628
4653
  SELECT id, payload
4629
- FROM ${this.collectionName}
4654
+ FROM ${this.col()}
4630
4655
  ${filterClause}
4631
4656
  LIMIT $${paramIndex}
4632
4657
  `;
4633
4658
  const countQuery = `
4634
4659
  SELECT COUNT(*)
4635
- FROM ${this.collectionName}
4660
+ FROM ${this.col()}
4636
4661
  ${filterClause}
4637
4662
  `;
4638
4663
  filterValues.push(topK);
@@ -4657,12 +4682,12 @@ var PGVector = class {
4657
4682
  if (result.rows.length > 0) {
4658
4683
  return result.rows[0].user_id;
4659
4684
  }
4660
- const randomUserId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
4685
+ const randomUserId2 = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
4661
4686
  await this.client.query(
4662
4687
  "INSERT INTO memory_migrations (user_id) VALUES ($1)",
4663
- [randomUserId]
4688
+ [randomUserId2]
4664
4689
  );
4665
- return randomUserId;
4690
+ return randomUserId2;
4666
4691
  }
4667
4692
  async setUserId(userId) {
4668
4693
  await this.client.query("DELETE FROM memory_migrations");
@@ -4963,7 +4988,7 @@ var parse_vision_messages = async (messages) => {
4963
4988
  };
4964
4989
 
4965
4990
  // src/oss/src/utils/telemetry.ts
4966
- var version = true ? "3.0.2" : "dev";
4991
+ var version = true ? "3.0.3" : "dev";
4967
4992
  var MEM0_TELEMETRY = true;
4968
4993
  var _a;
4969
4994
  try {
@@ -5865,6 +5890,69 @@ function scoreAndRank(semanticResults, bm25Scores, entityBoosts, threshold, topK
5865
5890
  return scored.slice(0, topK);
5866
5891
  }
5867
5892
 
5893
+ // src/client/config.ts
5894
+ async function getNodeFs() {
5895
+ var _a2, _b, _c, _d, _e;
5896
+ if (typeof process === "undefined" || !((_a2 = process.versions) == null ? void 0 : _a2.node)) return null;
5897
+ try {
5898
+ const [fs4, path3, os2, crypto] = await Promise.all([
5899
+ import("fs"),
5900
+ import("path"),
5901
+ import("os"),
5902
+ import("crypto")
5903
+ ]);
5904
+ const fsMod = (_b = fs4.default) != null ? _b : fs4;
5905
+ const pathMod = (_c = path3.default) != null ? _c : path3;
5906
+ const osMod = (_d = os2.default) != null ? _d : os2;
5907
+ const cryptoMod = (_e = crypto.default) != null ? _e : crypto;
5908
+ const dir = process.env.MEM0_DIR || pathMod.join(osMod.homedir(), ".mem0");
5909
+ return {
5910
+ fs: fsMod,
5911
+ path: pathMod,
5912
+ crypto: cryptoMod,
5913
+ configPath: pathMod.join(dir, "config.json")
5914
+ };
5915
+ } catch (e) {
5916
+ return null;
5917
+ }
5918
+ }
5919
+ function loadConfig(node) {
5920
+ try {
5921
+ if (!node.fs.existsSync(node.configPath)) return null;
5922
+ const parsed = JSON.parse(node.fs.readFileSync(node.configPath, "utf8"));
5923
+ return parsed && typeof parsed === "object" ? parsed : null;
5924
+ } catch (e) {
5925
+ return null;
5926
+ }
5927
+ }
5928
+ function writeConfig(node, config) {
5929
+ node.fs.mkdirSync(node.path.dirname(node.configPath), { recursive: true });
5930
+ node.fs.writeFileSync(node.configPath, JSON.stringify(config, null, 4));
5931
+ }
5932
+ function randomUserId(node) {
5933
+ if (typeof node.crypto.randomUUID === "function") {
5934
+ return node.crypto.randomUUID();
5935
+ }
5936
+ return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
5937
+ }
5938
+ async function getOrCreateMem0UserId() {
5939
+ var _a2;
5940
+ const node = await getNodeFs();
5941
+ if (!node) return null;
5942
+ try {
5943
+ const config = (_a2 = loadConfig(node)) != null ? _a2 : {};
5944
+ if (typeof config.user_id === "string" && config.user_id) {
5945
+ return config.user_id;
5946
+ }
5947
+ const userId = randomUserId(node);
5948
+ config.user_id = userId;
5949
+ writeConfig(node, config);
5950
+ return userId;
5951
+ } catch (e) {
5952
+ return null;
5953
+ }
5954
+ }
5955
+
5868
5956
  // src/oss/src/memory/index.ts
5869
5957
  var ENTITY_PARAMS = [
5870
5958
  "user_id",
@@ -6171,7 +6259,11 @@ var Memory = class _Memory {
6171
6259
  async _getTelemetryId() {
6172
6260
  try {
6173
6261
  if (!this.telemetryId || this.telemetryId === "anonymous" || this.telemetryId === "anonymous-supabase") {
6174
- this.telemetryId = await this.vectorStore.getUserId();
6262
+ this.telemetryId = await getOrCreateMem0UserId() || await this.vectorStore.getUserId();
6263
+ try {
6264
+ await this.vectorStore.setUserId(this.telemetryId);
6265
+ } catch (e) {
6266
+ }
6175
6267
  }
6176
6268
  return this.telemetryId;
6177
6269
  } catch (error) {