mem0ai 1.0.16 → 1.0.18

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/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "mem0ai",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "The Memory Layer For Your AI Apps",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
7
+ "test": "jest"
8
8
  },
9
9
  "types": "src/index.d.ts",
10
10
  "keywords": [
@@ -28,5 +28,16 @@
28
28
  "require": "./src/index.cjs",
29
29
  "import": "./dist/index.js"
30
30
  },
31
- "module": "dist/index.mjs"
32
- }
31
+ "module": "dist/index.mjs",
32
+ "devDependencies": {
33
+ "@types/node": "^22.7.6",
34
+ "dotenv": "^16.4.5",
35
+ "jest": "^29.7.0",
36
+ "rollup": "^4.24.0"
37
+ },
38
+ "dependencies": {
39
+ "axios": "^1.7.7",
40
+ "crypto": "^1.0.1",
41
+ "posthog-node": "^4.2.1"
42
+ }
43
+ }
package/src/index.cjs CHANGED
@@ -1,5 +1,70 @@
1
1
  'use strict';
2
2
 
3
+ var crypto = require('crypto');
4
+ var axios = require('axios');
5
+ var posthogNode = require('posthog-node');
6
+ var os = require('os');
7
+ var path = require('path');
8
+ var fs = require('fs');
9
+
10
+ process.env.MEM0_TELEMETRY !== "false";
11
+
12
+ class AnonymousTelemetry {
13
+ constructor(projectApiKey, host) {
14
+ this.client = new posthogNode.PostHog(projectApiKey, { host, flushAt: 1 });
15
+ }
16
+
17
+ async captureEvent(distinctId, eventName, properties = {}) {
18
+ const eventProperties = {
19
+ client_source: "nodejs",
20
+ client_version: getVersion(),
21
+ node_version: process.version,
22
+ os: process.platform,
23
+ os_version: os.release(),
24
+ os_arch: os.arch(),
25
+ ...properties,
26
+ };
27
+
28
+ try {
29
+ this.client.capture({
30
+ distinctId: distinctId,
31
+ event: eventName,
32
+ properties: eventProperties,
33
+ });
34
+ } catch (error) {
35
+ console.error("Error capturing event:", error);
36
+ }
37
+ }
38
+
39
+ async shutdown() {
40
+ return this.client.shutdown();
41
+ }
42
+ }
43
+
44
+ function getVersion() {
45
+ const packageJsonPath = path.join(__dirname, "..", "package.json");
46
+ const packageJsonContent = fs.readFileSync(packageJsonPath, "utf8");
47
+ const packageJson = JSON.parse(packageJsonContent);
48
+ return packageJson.version;
49
+ }
50
+
51
+ const telemetry = new AnonymousTelemetry(
52
+ "phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX",
53
+ "https://us.i.posthog.com"
54
+ );
55
+
56
+ async function captureClientEvent(eventName, instance, additionalData = {}) {
57
+ const eventData = {
58
+ function: `${instance.constructor.name}`,
59
+ ...additionalData,
60
+ };
61
+ await telemetry.captureEvent(
62
+ instance.telemetryId,
63
+ `client.${eventName}`,
64
+ eventData
65
+ );
66
+ }
67
+
3
68
  class APIError extends Error {
4
69
  constructor(message) {
5
70
  super(message);
@@ -28,7 +93,36 @@ class MemoryClient {
28
93
  'Content-Type': 'application/json'
29
94
  };
30
95
 
96
+ this.telemetryId = crypto.createHash('md5').update(this.apiKey).digest('hex');
97
+
98
+ this.client = axios.create({
99
+ baseURL: this.host,
100
+ headers: { Authorization: `Token ${this.apiKey}` },
101
+ timeout: 60000,
102
+ });
103
+
104
+ captureClientEvent('init', this);
105
+
31
106
  this._validateApiKey();
107
+
108
+ // Apply error handler and telemetry to methods
109
+ this.add = this.wrapMethod('add', this.add);
110
+ this.get = this.wrapMethod('get', this.get);
111
+ this.getAll = this.wrapMethod('get_all', this.getAll);
112
+ this.search = this.wrapMethod('search', this.search);
113
+ this.delete = this.wrapMethod('delete', this.delete);
114
+ this.deleteAll = this.wrapMethod('delete_all', this.deleteAll);
115
+ this.history = this.wrapMethod('history', this.history);
116
+ this.users = this.wrapMethod('users', this.users);
117
+ this.deleteUser = this.wrapMethod('delete_user', this.deleteUser);
118
+ this.deleteUsers = this.wrapMethod('delete_users', this.deleteUsers);
119
+ }
120
+
121
+ wrapMethod(methodName, method) {
122
+ return async function (...args) {
123
+ await captureClientEvent(methodName, this);
124
+ return method.apply(this, args);
125
+ }.bind(this);
32
126
  }
33
127
 
34
128
  _validateApiKey() {
@@ -141,6 +235,14 @@ class MemoryClient {
141
235
  return response;
142
236
  }
143
237
 
238
+ async deleteUser(entityId, entity = { type: 'user' }) {
239
+ const response = await this._fetchWithErrorHandling(`${this.host}/v1/entities/${entity.type}/${entityId}/`, {
240
+ method: 'DELETE',
241
+ headers: this.headers
242
+ });
243
+ return response;
244
+ }
245
+
144
246
  async deleteUsers() {
145
247
  const entities = await this.users();
146
248
  for (const entity of entities.results) {
@@ -175,7 +277,6 @@ class MemoryClient {
175
277
  _prepareParams(options) {
176
278
  return Object.fromEntries(Object.entries(options).filter(([_, v]) => v != null));
177
279
  }
178
-
179
280
  }
180
281
 
181
282
  module.exports = MemoryClient;
package/src/index.d.ts CHANGED
@@ -7,14 +7,76 @@ declare module 'mem0ai' {
7
7
  filters?: Record<string, any>;
8
8
  }
9
9
 
10
+ enum API_VERSION {
11
+ V1 = 'v1',
12
+ V2 = 'v2',
13
+ }
14
+
15
+ export interface Messages {
16
+ role: string;
17
+ content: string;
18
+ }
19
+
20
+ export interface MemoryHistory {
21
+ id: string;
22
+ memory_id: string;
23
+ input: Array<Messages>;
24
+ old_memory: string | null;
25
+ new_memory: string | null;
26
+ user_id: string;
27
+ categories: Array<string>;
28
+ event: Event | string;
29
+ created_at: Date;
30
+ updated_at: Date;
31
+ }
32
+
10
33
  export interface SearchOptions extends MemoryOptions {
11
- api_version?: 'v1' | 'v2';
34
+ api_version?: API_VERSION | string;
12
35
  limit?: number;
13
36
  }
14
37
 
38
+ enum Event{
39
+ ADD = 'ADD',
40
+ UPDATE = 'UPDATE',
41
+ DELETE = 'DELETE',
42
+ NOOP = 'NOOP',
43
+ }
44
+
45
+ export interface MemoryData {
46
+ memory: string;
47
+ }
48
+
15
49
  export interface Memory {
16
50
  id: string;
17
- messages: Array<{ role: string; content: string }>;
51
+ messages?: Array<Messages>;
52
+ event?: Event | string;
53
+ data?: MemoryData | null;
54
+ memory?: string;
55
+ user_id?: string;
56
+ hash?: string;
57
+ categories?: Array<string>;
58
+ created_at?: Date;
59
+ updated_at?: Date;
60
+ memory_type?: string;
61
+ score?: number;
62
+ metadata?: any | null;
63
+ }
64
+
65
+ export interface User {
66
+ id: string;
67
+ name: string;
68
+ created_at: Date;
69
+ updated_at: Date;
70
+ total_memories: number;
71
+ owner: string;
72
+ type: string;
73
+ }
74
+
75
+ export interface AllUsers {
76
+ count: number;
77
+ results: Array<User>;
78
+ next: any;
79
+ previous: any;
18
80
  }
19
81
 
20
82
  export class MemoryClient {
@@ -28,24 +90,26 @@ declare module 'mem0ai' {
28
90
  add(
29
91
  messages: string | Array<{ role: string; content: string }>,
30
92
  options?: MemoryOptions
31
- ): Promise<Memory[]>;
93
+ ): Promise<Array<Memory>>;
32
94
 
33
95
  get(memoryId: string): Promise<Memory>;
34
96
 
35
- getAll(options?: MemoryOptions & { api_version?: 'v1' | 'v2' }): Promise<{ results: Memory[] }>;
97
+ getAll(options?: MemoryOptions & { api_version?: 'v1' | 'v2' }): Promise<Array<Memory>>;
36
98
 
37
- search(query: string, options?: SearchOptions): Promise<{ results: Memory[] }>;
99
+ search(query: string, options?: SearchOptions): Promise<Array<Memory>>;
38
100
 
39
- delete(memoryId: string): Promise<any>;
101
+ delete(memoryId: string): Promise<{ message: string }>;
40
102
 
41
- deleteAll(options?: MemoryOptions): Promise<any>;
103
+ deleteAll(options?: MemoryOptions): Promise<{ message: string }>;
42
104
 
43
- history(memoryId: string): Promise<any>;
105
+ history(memoryId: string): Promise<Array<MemoryHistory>>;
44
106
 
45
- users(): Promise<any>;
107
+ users(): Promise<AllUsers>;
46
108
 
47
109
  deleteUsers(): Promise<{ message: string }>;
48
110
 
111
+ deleteUser(entityId: string, entity?: { type: string }): Promise<{ message: string }>;
112
+
49
113
  private _validateApiKey(): Promise<void>;
50
114
 
51
115
  private _preparePayload(
package/src/index.js CHANGED
@@ -1,3 +1,7 @@
1
+ import crypto from 'crypto';
2
+ import axios from 'axios';
3
+ import { captureClientEvent } from './telemetry.js';
4
+
1
5
  class APIError extends Error {
2
6
  constructor(message) {
3
7
  super(message);
@@ -26,7 +30,36 @@ class MemoryClient {
26
30
  'Content-Type': 'application/json'
27
31
  };
28
32
 
33
+ this.telemetryId = crypto.createHash('md5').update(this.apiKey).digest('hex');
34
+
35
+ this.client = axios.create({
36
+ baseURL: this.host,
37
+ headers: { Authorization: `Token ${this.apiKey}` },
38
+ timeout: 60000,
39
+ });
40
+
41
+ captureClientEvent('init', this);
42
+
29
43
  this._validateApiKey();
44
+
45
+ // Apply error handler and telemetry to methods
46
+ this.add = this.wrapMethod('add', this.add);
47
+ this.get = this.wrapMethod('get', this.get);
48
+ this.getAll = this.wrapMethod('get_all', this.getAll);
49
+ this.search = this.wrapMethod('search', this.search);
50
+ this.delete = this.wrapMethod('delete', this.delete);
51
+ this.deleteAll = this.wrapMethod('delete_all', this.deleteAll);
52
+ this.history = this.wrapMethod('history', this.history);
53
+ this.users = this.wrapMethod('users', this.users);
54
+ this.deleteUser = this.wrapMethod('delete_user', this.deleteUser);
55
+ this.deleteUsers = this.wrapMethod('delete_users', this.deleteUsers);
56
+ }
57
+
58
+ wrapMethod(methodName, method) {
59
+ return async function (...args) {
60
+ await captureClientEvent(methodName, this);
61
+ return method.apply(this, args);
62
+ }.bind(this);
30
63
  }
31
64
 
32
65
  _validateApiKey() {
@@ -139,6 +172,14 @@ class MemoryClient {
139
172
  return response;
140
173
  }
141
174
 
175
+ async deleteUser(entityId, entity = { type: 'user' }) {
176
+ const response = await this._fetchWithErrorHandling(`${this.host}/v1/entities/${entity.type}/${entityId}/`, {
177
+ method: 'DELETE',
178
+ headers: this.headers
179
+ });
180
+ return response;
181
+ }
182
+
142
183
  async deleteUsers() {
143
184
  const entities = await this.users();
144
185
  for (const entity of entities.results) {
@@ -173,7 +214,6 @@ class MemoryClient {
173
214
  _prepareParams(options) {
174
215
  return Object.fromEntries(Object.entries(options).filter(([_, v]) => v != null));
175
216
  }
176
-
177
217
  }
178
218
 
179
- export default MemoryClient;
219
+ export default MemoryClient;
@@ -0,0 +1,64 @@
1
+ import { PostHog } from "posthog-node";
2
+ import os from "os";
3
+ import path from "path";
4
+ import fs from "fs";
5
+
6
+ const MEM0_TELEMETRY = process.env.MEM0_TELEMETRY !== "false";
7
+
8
+ class AnonymousTelemetry {
9
+ constructor(projectApiKey, host) {
10
+ this.client = new PostHog(projectApiKey, { host, flushAt: 1 });
11
+ }
12
+
13
+ async captureEvent(distinctId, eventName, properties = {}) {
14
+ const eventProperties = {
15
+ client_source: "nodejs",
16
+ client_version: getVersion(),
17
+ node_version: process.version,
18
+ os: process.platform,
19
+ os_version: os.release(),
20
+ os_arch: os.arch(),
21
+ ...properties,
22
+ };
23
+
24
+ try {
25
+ this.client.capture({
26
+ distinctId: distinctId,
27
+ event: eventName,
28
+ properties: eventProperties,
29
+ });
30
+ } catch (error) {
31
+ console.error("Error capturing event:", error);
32
+ }
33
+ }
34
+
35
+ async shutdown() {
36
+ return this.client.shutdown();
37
+ }
38
+ }
39
+
40
+ function getVersion() {
41
+ const packageJsonPath = path.join(__dirname, "..", "package.json");
42
+ const packageJsonContent = fs.readFileSync(packageJsonPath, "utf8");
43
+ const packageJson = JSON.parse(packageJsonContent);
44
+ return packageJson.version;
45
+ }
46
+
47
+ const telemetry = new AnonymousTelemetry(
48
+ "phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX",
49
+ "https://us.i.posthog.com"
50
+ );
51
+
52
+ async function captureClientEvent(eventName, instance, additionalData = {}) {
53
+ const eventData = {
54
+ function: `${instance.constructor.name}`,
55
+ ...additionalData,
56
+ };
57
+ await telemetry.captureEvent(
58
+ instance.telemetryId,
59
+ `client.${eventName}`,
60
+ eventData
61
+ );
62
+ }
63
+
64
+ export { telemetry, captureClientEvent };