mem0ai 2.4.6 → 3.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -75,6 +75,37 @@ async function captureClientEvent(eventName, instance, additionalData = {}) {
75
75
  );
76
76
  }
77
77
 
78
+ // src/client/utils.ts
79
+ function camelToSnake(str) {
80
+ if (str === str.toUpperCase()) return str;
81
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
82
+ }
83
+ function snakeToCamel(str) {
84
+ return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
85
+ }
86
+ function camelToSnakeKeys(obj) {
87
+ if (obj === null || obj === void 0 || typeof obj !== "object") return obj;
88
+ if (Array.isArray(obj)) return obj.map(camelToSnakeKeys);
89
+ if (obj instanceof Date) return obj;
90
+ return Object.fromEntries(
91
+ Object.entries(obj).map(([key, value]) => [
92
+ camelToSnake(key),
93
+ camelToSnakeKeys(value)
94
+ ])
95
+ );
96
+ }
97
+ function snakeToCamelKeys(obj) {
98
+ if (obj === null || obj === void 0 || typeof obj !== "object") return obj;
99
+ if (Array.isArray(obj)) return obj.map(snakeToCamelKeys);
100
+ if (obj instanceof Date) return obj;
101
+ return Object.fromEntries(
102
+ Object.entries(obj).map(([key, value]) => [
103
+ snakeToCamel(key),
104
+ snakeToCamelKeys(value)
105
+ ])
106
+ );
107
+ }
108
+
78
109
  // src/common/exceptions.ts
79
110
  var MemoryError = class extends Error {
80
111
  constructor(message, errorCode, options = {}) {
@@ -173,6 +204,26 @@ function createExceptionFromResponse(statusCode, responseText, options = {}) {
173
204
  }
174
205
 
175
206
  // src/client/mem0.ts
207
+ var ENTITY_PARAMS = [
208
+ "user_id",
209
+ "agent_id",
210
+ "app_id",
211
+ "run_id",
212
+ "userId",
213
+ "agentId",
214
+ "appId",
215
+ "runId"
216
+ ];
217
+ function rejectTopLevelEntityParams(options, methodName) {
218
+ const invalidKeys = Object.keys(options != null ? options : {}).filter(
219
+ (k) => ENTITY_PARAMS.includes(k)
220
+ );
221
+ if (invalidKeys.length > 0) {
222
+ throw new Error(
223
+ `Top-level entity parameters [${invalidKeys.join(", ")}] are not supported in ${methodName}(). Use filters: { user_id: "..." } instead.`
224
+ );
225
+ }
226
+ }
176
227
  var APIError = class extends Error {
177
228
  constructor(message) {
178
229
  super(message);
@@ -191,25 +242,11 @@ var MemoryClient = class {
191
242
  throw new Error("Mem0 API key cannot be empty");
192
243
  }
193
244
  }
194
- _validateOrgProject() {
195
- if (this.organizationName === null && this.projectName !== null || this.organizationName !== null && this.projectName === null) {
196
- console.warn(
197
- "Warning: Both organizationName and projectName must be provided together when using either. This will be removed from version 1.0.40. Note that organizationName/projectName are being deprecated in favor of organizationId/projectId."
198
- );
199
- }
200
- if (this.organizationId === null && this.projectId !== null || this.organizationId !== null && this.projectId === null) {
201
- console.warn(
202
- "Warning: Both organizationId and projectId must be provided together when using either. This will be removed from version 1.0.40."
203
- );
204
- }
205
- }
206
245
  constructor(options) {
207
246
  this.apiKey = options.apiKey;
208
247
  this.host = options.host || "https://api.mem0.ai";
209
- this.organizationName = options.organizationName || null;
210
- this.projectName = options.projectName || null;
211
- this.organizationId = options.organizationId || null;
212
- this.projectId = options.projectId || null;
248
+ this.organizationId = null;
249
+ this.projectId = null;
213
250
  this.headers = {
214
251
  Authorization: `Token ${this.apiKey}`,
215
252
  "Content-Type": "application/json"
@@ -229,9 +266,7 @@ var MemoryClient = class {
229
266
  if (!this.telemetryId) {
230
267
  this.telemetryId = generateHash(this.apiKey);
231
268
  }
232
- this._validateOrgProject();
233
269
  captureClientEvent("init", this, {
234
- api_version: "v1",
235
270
  client_type: "MemoryClient"
236
271
  }).catch((error) => {
237
272
  console.error("Failed to capture event:", error);
@@ -267,12 +302,12 @@ var MemoryClient = class {
267
302
  throw createExceptionFromResponse(response.status, errorData);
268
303
  }
269
304
  const jsonResponse = await response.json();
270
- return jsonResponse;
305
+ return snakeToCamelKeys(jsonResponse);
271
306
  }
272
307
  _preparePayload(messages, options) {
273
308
  const payload = {};
274
309
  payload.messages = messages;
275
- return { ...payload, ...options };
310
+ return camelToSnakeKeys({ ...payload, ...options });
276
311
  }
277
312
  _prepareParams(options) {
278
313
  return Object.fromEntries(
@@ -296,10 +331,10 @@ var MemoryClient = class {
296
331
  if (response.status !== "ok") {
297
332
  throw new APIError(response.message || "API Key is invalid");
298
333
  }
299
- const { org_id, project_id, user_email } = response;
300
- if (org_id && !this.organizationId) this.organizationId = org_id;
301
- if (project_id && !this.projectId) this.projectId = project_id;
302
- if (user_email) this.telemetryId = user_email;
334
+ const { orgId, projectId, userEmail } = response;
335
+ if (orgId) this.organizationId = orgId;
336
+ if (projectId) this.projectId = projectId;
337
+ if (userEmail) this.telemetryId = userEmail;
303
338
  } catch (error) {
304
339
  if (error instanceof MemoryError || error instanceof APIError) {
305
340
  throw error;
@@ -312,25 +347,11 @@ var MemoryClient = class {
312
347
  }
313
348
  async add(messages, options = {}) {
314
349
  if (this.telemetryId === "") await this.ping();
315
- this._validateOrgProject();
316
- if (this.organizationName != null && this.projectName != null) {
317
- options.org_name = this.organizationName;
318
- options.project_name = this.projectName;
319
- }
320
- if (this.organizationId != null && this.projectId != null) {
321
- options.org_id = this.organizationId;
322
- options.project_id = this.projectId;
323
- if (options.org_name) delete options.org_name;
324
- if (options.project_name) delete options.project_name;
325
- }
326
- if (options.api_version) {
327
- options.version = options.api_version.toString() || "v2";
328
- }
329
350
  const payload = this._preparePayload(messages, options);
330
351
  const payloadKeys = Object.keys(payload);
331
352
  this._captureEvent("add", [payloadKeys]);
332
353
  const response = await this._fetchWithErrorHandling(
333
- `${this.host}/v1/memories/`,
354
+ `${this.host}/v3/memories/`,
334
355
  {
335
356
  method: "POST",
336
357
  headers: this.headers,
@@ -350,7 +371,6 @@ var MemoryClient = class {
350
371
  );
351
372
  }
352
373
  if (this.telemetryId === "") await this.ping();
353
- this._validateOrgProject();
354
374
  const payload = {};
355
375
  if (text !== void 0) payload.text = text;
356
376
  if (metadata !== void 0) payload.metadata = metadata;
@@ -378,62 +398,42 @@ var MemoryClient = class {
378
398
  );
379
399
  }
380
400
  async getAll(options) {
401
+ var _a2;
402
+ rejectTopLevelEntityParams(options, "getAll");
381
403
  if (this.telemetryId === "") await this.ping();
382
- this._validateOrgProject();
383
404
  const payloadKeys = Object.keys(options || {});
384
405
  this._captureEvent("get_all", [payloadKeys]);
385
- const { api_version, page, page_size, ...otherOptions } = options != null ? options : {};
386
- if (this.organizationName != null && this.projectName != null) {
387
- otherOptions.org_name = this.organizationName;
388
- otherOptions.project_name = this.projectName;
389
- }
390
- let appendedParams = "";
391
- let paginated_response = false;
392
- if (page && page_size) {
393
- appendedParams += `page=${page}&page_size=${page_size}`;
394
- paginated_response = true;
395
- }
396
- if (this.organizationId != null && this.projectId != null) {
397
- otherOptions.org_id = this.organizationId;
398
- otherOptions.project_id = this.projectId;
399
- if (otherOptions.org_name) delete otherOptions.org_name;
400
- if (otherOptions.project_name) delete otherOptions.project_name;
401
- }
402
- if (api_version === "v2") {
403
- let url = paginated_response ? `${this.host}/v2/memories/?${appendedParams}` : `${this.host}/v2/memories/`;
404
- return this._fetchWithErrorHandling(url, {
405
- method: "POST",
406
- headers: this.headers,
407
- body: JSON.stringify(otherOptions)
408
- });
409
- } else {
410
- const params = new URLSearchParams(this._prepareParams(otherOptions));
411
- const url = paginated_response ? `${this.host}/v1/memories/?${params}&${appendedParams}` : `${this.host}/v1/memories/?${params}`;
412
- return this._fetchWithErrorHandling(url, {
413
- headers: this.headers
414
- });
415
- }
406
+ const { page, pageSize, filters, ...rest } = options != null ? options : {};
407
+ const body = {
408
+ output_format: "v1.1",
409
+ ...camelToSnakeKeys(rest),
410
+ ...filters && { filters }
411
+ };
412
+ let url = `${this.host}/v2/memories/`;
413
+ if (page && pageSize) {
414
+ url += `?page=${page}&page_size=${pageSize}`;
415
+ }
416
+ const response = await this._fetchWithErrorHandling(url, {
417
+ method: "POST",
418
+ headers: this.headers,
419
+ body: JSON.stringify(body)
420
+ });
421
+ return Array.isArray(response) ? response : (_a2 = response == null ? void 0 : response.results) != null ? _a2 : response;
416
422
  }
417
423
  async search(query, options) {
424
+ rejectTopLevelEntityParams(options, "search");
418
425
  if (this.telemetryId === "") await this.ping();
419
- this._validateOrgProject();
420
426
  const payloadKeys = Object.keys(options || {});
421
427
  this._captureEvent("search", [payloadKeys]);
422
- const { api_version, ...otherOptions } = options != null ? options : {};
423
- const payload = { query, ...otherOptions };
424
- if (this.organizationName != null && this.projectName != null) {
425
- payload.org_name = this.organizationName;
426
- payload.project_name = this.projectName;
427
- }
428
- if (this.organizationId != null && this.projectId != null) {
429
- payload.org_id = this.organizationId;
430
- payload.project_id = this.projectId;
431
- if (payload.org_name) delete payload.org_name;
432
- if (payload.project_name) delete payload.project_name;
433
- }
434
- const endpoint = api_version === "v2" ? "/v2/memories/search/" : "/v1/memories/search/";
428
+ const { filters, ...rest } = options != null ? options : {};
429
+ const payload = {
430
+ query,
431
+ output_format: "v1.1",
432
+ ...camelToSnakeKeys(rest),
433
+ ...filters && { filters }
434
+ };
435
435
  const response = await this._fetchWithErrorHandling(
436
- `${this.host}${endpoint}`,
436
+ `${this.host}/v3/memories/search/`,
437
437
  {
438
438
  method: "POST",
439
439
  headers: this.headers,
@@ -455,20 +455,10 @@ var MemoryClient = class {
455
455
  }
456
456
  async deleteAll(options = {}) {
457
457
  if (this.telemetryId === "") await this.ping();
458
- this._validateOrgProject();
459
458
  const payloadKeys = Object.keys(options || {});
460
459
  this._captureEvent("delete_all", [payloadKeys]);
461
- if (this.organizationName != null && this.projectName != null) {
462
- options.org_name = this.organizationName;
463
- options.project_name = this.projectName;
464
- }
465
- if (this.organizationId != null && this.projectId != null) {
466
- options.org_id = this.organizationId;
467
- options.project_id = this.projectId;
468
- if (options.org_name) delete options.org_name;
469
- if (options.project_name) delete options.project_name;
470
- }
471
- const params = new URLSearchParams(this._prepareParams(options));
460
+ const snakeOptions = camelToSnakeKeys(this._prepareParams(options));
461
+ const params = new URLSearchParams(snakeOptions);
472
462
  const response = await this._fetchWithErrorHandling(
473
463
  `${this.host}/v1/memories/?${params}`,
474
464
  {
@@ -489,28 +479,17 @@ var MemoryClient = class {
489
479
  );
490
480
  return response;
491
481
  }
492
- async users() {
482
+ async users(options) {
493
483
  if (this.telemetryId === "") await this.ping();
494
- this._validateOrgProject();
495
484
  this._captureEvent("users", []);
496
- const options = {};
497
- if (this.organizationName != null && this.projectName != null) {
498
- options.org_name = this.organizationName;
499
- options.project_name = this.projectName;
500
- }
501
- if (this.organizationId != null && this.projectId != null) {
502
- options.org_id = this.organizationId;
503
- options.project_id = this.projectId;
504
- if (options.org_name) delete options.org_name;
505
- if (options.project_name) delete options.project_name;
506
- }
507
- const params = new URLSearchParams(options);
508
- const response = await this._fetchWithErrorHandling(
509
- `${this.host}/v1/entities/?${params}`,
510
- {
511
- headers: this.headers
512
- }
513
- );
485
+ let url = `${this.host}/v1/entities/`;
486
+ const params = [];
487
+ if (options == null ? void 0 : options.page) params.push(`page=${options.page}`);
488
+ if (options == null ? void 0 : options.pageSize) params.push(`page_size=${options.pageSize}`);
489
+ if (params.length) url += `?${params.join("&")}`;
490
+ const response = await this._fetchWithErrorHandling(url, {
491
+ headers: this.headers
492
+ });
514
493
  return response;
515
494
  }
516
495
  /**
@@ -533,17 +512,16 @@ var MemoryClient = class {
533
512
  }
534
513
  async deleteUsers(params = {}) {
535
514
  if (this.telemetryId === "") await this.ping();
536
- this._validateOrgProject();
537
515
  let to_delete = [];
538
- const { user_id, agent_id, app_id, run_id } = params;
539
- if (user_id) {
540
- to_delete = [{ type: "user", name: user_id }];
541
- } else if (agent_id) {
542
- to_delete = [{ type: "agent", name: agent_id }];
543
- } else if (app_id) {
544
- to_delete = [{ type: "app", name: app_id }];
545
- } else if (run_id) {
546
- to_delete = [{ type: "run", name: run_id }];
516
+ const { userId, agentId, appId, runId } = params;
517
+ if (userId) {
518
+ to_delete = [{ type: "user", name: userId }];
519
+ } else if (agentId) {
520
+ to_delete = [{ type: "agent", name: agentId }];
521
+ } else if (appId) {
522
+ to_delete = [{ type: "app", name: appId }];
523
+ } else if (runId) {
524
+ to_delete = [{ type: "run", name: runId }];
547
525
  } else {
548
526
  const entities = await this.users();
549
527
  to_delete = entities.results.map((entity) => ({
@@ -554,25 +532,9 @@ var MemoryClient = class {
554
532
  if (to_delete.length === 0) {
555
533
  throw new Error("No entities to delete");
556
534
  }
557
- const requestOptions = {};
558
- if (this.organizationName != null && this.projectName != null) {
559
- requestOptions.org_name = this.organizationName;
560
- requestOptions.project_name = this.projectName;
561
- }
562
- if (this.organizationId != null && this.projectId != null) {
563
- requestOptions.org_id = this.organizationId;
564
- requestOptions.project_id = this.projectId;
565
- if (requestOptions.org_name) delete requestOptions.org_name;
566
- if (requestOptions.project_name) delete requestOptions.project_name;
567
- }
568
535
  for (const entity of to_delete) {
569
536
  try {
570
- await this.client.delete(
571
- `/v2/entities/${entity.type}/${entity.name}/`,
572
- {
573
- params: requestOptions
574
- }
575
- );
537
+ await this.client.delete(`/v2/entities/${entity.type}/${entity.name}/`);
576
538
  } catch (error) {
577
539
  throw new APIError(
578
540
  `Failed to delete ${entity.type} ${entity.name}: ${error.message}`
@@ -580,16 +542,10 @@ var MemoryClient = class {
580
542
  }
581
543
  }
582
544
  this._captureEvent("delete_users", [
583
- {
584
- user_id,
585
- agent_id,
586
- app_id,
587
- run_id,
588
- sync_type: "sync"
589
- }
545
+ { userId, agentId, appId, runId, sync_type: "sync" }
590
546
  ]);
591
547
  return {
592
- message: user_id || agent_id || app_id || run_id ? "Entity deleted successfully." : "All users, agents, apps and runs deleted."
548
+ message: userId || agentId || appId || runId ? "Entity deleted successfully." : "All users, agents, apps and runs deleted."
593
549
  };
594
550
  }
595
551
  async batchUpdate(memories) {
@@ -627,7 +583,6 @@ var MemoryClient = class {
627
583
  }
628
584
  async getProject(options) {
629
585
  if (this.telemetryId === "") await this.ping();
630
- this._validateOrgProject();
631
586
  const payloadKeys = Object.keys(options || {});
632
587
  this._captureEvent("get_project", [payloadKeys]);
633
588
  const { fields } = options;
@@ -637,7 +592,7 @@ var MemoryClient = class {
637
592
  );
638
593
  }
639
594
  const params = new URLSearchParams();
640
- fields == null ? void 0 : fields.forEach((field) => params.append("fields", field));
595
+ fields == null ? void 0 : fields.forEach((field) => params.append("fields", camelToSnake(field)));
641
596
  const response = await this._fetchWithErrorHandling(
642
597
  `${this.host}/api/v1/orgs/organizations/${this.organizationId}/projects/${this.projectId}/?${params.toString()}`,
643
598
  {
@@ -648,7 +603,6 @@ var MemoryClient = class {
648
603
  }
649
604
  async updateProject(prompts) {
650
605
  if (this.telemetryId === "") await this.ping();
651
- this._validateOrgProject();
652
606
  this._captureEvent("update_project", []);
653
607
  if (!(this.organizationId && this.projectId)) {
654
608
  throw new Error(
@@ -660,7 +614,7 @@ var MemoryClient = class {
660
614
  {
661
615
  method: "PATCH",
662
616
  headers: this.headers,
663
- body: JSON.stringify(prompts)
617
+ body: JSON.stringify(camelToSnakeKeys(prompts))
664
618
  }
665
619
  );
666
620
  return response;
@@ -735,45 +689,47 @@ var MemoryClient = class {
735
689
  {
736
690
  method: "POST",
737
691
  headers: this.headers,
738
- body: JSON.stringify(data)
692
+ body: JSON.stringify(camelToSnakeKeys(data))
739
693
  }
740
694
  );
741
695
  return response;
742
696
  }
743
697
  async createMemoryExport(data) {
744
- var _a2, _b;
745
698
  if (this.telemetryId === "") await this.ping();
746
699
  this._captureEvent("create_memory_export", []);
747
700
  if (!data.filters || !data.schema) {
748
701
  throw new Error("Missing filters or schema");
749
702
  }
750
- data.org_id = ((_a2 = this.organizationId) == null ? void 0 : _a2.toString()) || null;
751
- data.project_id = ((_b = this.projectId) == null ? void 0 : _b.toString()) || null;
703
+ const { filters, ...rest } = data;
752
704
  const response = await this._fetchWithErrorHandling(
753
705
  `${this.host}/v1/exports/`,
754
706
  {
755
707
  method: "POST",
756
708
  headers: this.headers,
757
- body: JSON.stringify(data)
709
+ body: JSON.stringify({
710
+ ...camelToSnakeKeys(rest),
711
+ filters
712
+ })
758
713
  }
759
714
  );
760
715
  return response;
761
716
  }
762
717
  async getMemoryExport(data) {
763
- var _a2, _b;
764
718
  if (this.telemetryId === "") await this.ping();
765
719
  this._captureEvent("get_memory_export", []);
766
- if (!data.memory_export_id && !data.filters) {
767
- throw new Error("Missing memory_export_id or filters");
720
+ if (!data.memoryExportId && !data.filters) {
721
+ throw new Error("Missing memoryExportId or filters");
768
722
  }
769
- data.org_id = ((_a2 = this.organizationId) == null ? void 0 : _a2.toString()) || "";
770
- data.project_id = ((_b = this.projectId) == null ? void 0 : _b.toString()) || "";
723
+ const { filters, ...rest } = data;
771
724
  const response = await this._fetchWithErrorHandling(
772
725
  `${this.host}/v1/exports/get/`,
773
726
  {
774
727
  method: "POST",
775
728
  headers: this.headers,
776
- body: JSON.stringify(data)
729
+ body: JSON.stringify({
730
+ ...camelToSnakeKeys(rest),
731
+ ...filters && { filters }
732
+ })
777
733
  }
778
734
  );
779
735
  return response;