mem0ai 1.0.11 → 1.0.13
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/README.md +74 -18
- package/package.json +4 -4
- package/src/index.d.ts +60 -29
- package/src/index.js +208 -215
- package/src/telemetry.js +12 -39
package/README.md
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# Mem0 - The Memory layer for your AI apps
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
Mem0 is a self-improving memory layer for LLM applications, enabling personalized AI experiences that save costs and delight users.
|
|
4
5
|
|
|
5
6
|
Get started with Mem0 Platform in minutes using the Node.js client.
|
|
6
7
|
|
|
7
8
|
## 1. Installation
|
|
8
9
|
|
|
9
|
-
Install the Mem0
|
|
10
|
+
Install the Mem0 package:
|
|
10
11
|
|
|
11
12
|
```bash
|
|
12
|
-
npm
|
|
13
|
+
npm i mem0ai
|
|
13
14
|
```
|
|
14
15
|
|
|
15
16
|
## 2. API Key Setup
|
|
@@ -20,15 +21,18 @@ npm install mem0ai
|
|
|
20
21
|
## 3. Instantiate Client
|
|
21
22
|
|
|
22
23
|
```javascript
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
import MemoryClient from 'mem0ai';
|
|
25
|
+
|
|
26
|
+
const apiKey = 'your-api-key-here';
|
|
27
|
+
const client = new MemoryClient(apiKey);
|
|
25
28
|
```
|
|
26
29
|
|
|
27
30
|
Alternatively, you can set the `MEM0_API_KEY` environment variable and instantiate the client without passing the API key:
|
|
28
31
|
|
|
29
32
|
```javascript
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
import MemoryClient from 'mem0ai';
|
|
34
|
+
|
|
35
|
+
const client = new MemoryClient(process.env.MEM0_API_KEY);
|
|
32
36
|
```
|
|
33
37
|
|
|
34
38
|
## 4. Memory Operations
|
|
@@ -244,18 +248,19 @@ client.add("Delete all of my food preferences", { user_id: "alex" })
|
|
|
244
248
|
|
|
245
249
|
## 5. Error Handling
|
|
246
250
|
|
|
247
|
-
The MemoryClient throws
|
|
251
|
+
The MemoryClient throws errors for any API-related issues. You can catch and handle these errors as follows:
|
|
248
252
|
|
|
249
253
|
```javascript
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
.
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
254
|
+
try {
|
|
255
|
+
const result = await client.add(messages, { user_id: "alex" });
|
|
256
|
+
console.log(result);
|
|
257
|
+
} catch (error) {
|
|
258
|
+
if (error.name === 'APIError') {
|
|
259
|
+
console.error('API Error:', error.message);
|
|
260
|
+
} else {
|
|
261
|
+
console.error('Unexpected error:', error);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
259
264
|
```
|
|
260
265
|
|
|
261
266
|
## 6. Using with async/await
|
|
@@ -265,16 +270,67 @@ All methods of the MemoryClient return promises, so you can use them with async/
|
|
|
265
270
|
```javascript
|
|
266
271
|
async function addMemory() {
|
|
267
272
|
try {
|
|
273
|
+
const messages = [
|
|
274
|
+
{ role: "user", content: "Hi, I'm Alex. I'm a vegetarian and I'm allergic to nuts." },
|
|
275
|
+
{ role: "assistant", content: "Hello Alex! I've noted that you're a vegetarian and have a nut allergy. I'll keep this in mind for any food-related recommendations or discussions." }
|
|
276
|
+
];
|
|
268
277
|
const result = await client.add(messages, { user_id: "alex" });
|
|
269
|
-
console.log(result);
|
|
278
|
+
console.log('Memory added:', result);
|
|
279
|
+
|
|
280
|
+
const searchResult = await client.search("What are Alex's dietary restrictions?", { user_id: "alex" });
|
|
281
|
+
console.log('Search result:', searchResult);
|
|
270
282
|
} catch (error) {
|
|
271
|
-
console.error('Error
|
|
283
|
+
console.error('Error:', error);
|
|
272
284
|
}
|
|
273
285
|
}
|
|
274
286
|
|
|
275
287
|
addMemory();
|
|
276
288
|
```
|
|
277
289
|
|
|
290
|
+
## 7. Testing the Client
|
|
291
|
+
|
|
292
|
+
To test the MemoryClient in a Node.js environment, you can create a simple script:
|
|
293
|
+
|
|
294
|
+
```javascript
|
|
295
|
+
// test-mem0.js
|
|
296
|
+
import MemoryClient from 'mem0ai';
|
|
297
|
+
|
|
298
|
+
const apiKey = 'your-api-key-here';
|
|
299
|
+
const client = new MemoryClient(apiKey);
|
|
300
|
+
|
|
301
|
+
async function testMemoryOperations() {
|
|
302
|
+
try {
|
|
303
|
+
// Add a memory
|
|
304
|
+
const addResult = await client.add([
|
|
305
|
+
{ role: "user", content: "My favorite color is blue." }
|
|
306
|
+
], { user_id: "test-user" });
|
|
307
|
+
console.log('Memory added:', addResult);
|
|
308
|
+
|
|
309
|
+
// Search for memories
|
|
310
|
+
const searchResult = await client.search("What's my favorite color?", { user_id: "test-user" });
|
|
311
|
+
console.log('Search result:', searchResult);
|
|
312
|
+
|
|
313
|
+
// Get all memories
|
|
314
|
+
const allMemories = await client.getAll({ user_id: "test-user" });
|
|
315
|
+
console.log('All memories:', allMemories);
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.error('Error:', error);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
testMemoryOperations();
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Run this script using Node.js:
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
node test-mem0.js
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
This will perform basic operations (add, search, getAll) and log the results, allowing you to verify that the client is working correctly with your API key.
|
|
331
|
+
|
|
332
|
+
Remember to replace 'your-api-key-here' with your actual Mem0 API key when testing.
|
|
333
|
+
|
|
278
334
|
## Getting Help
|
|
279
335
|
|
|
280
336
|
If you have any questions or need assistance, please reach out to us:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mem0ai",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "The Memory layer for your AI apps",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
"author": "Deshraj Yadav",
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"
|
|
23
|
-
"posthog-node": "^4.2.0"
|
|
22
|
+
"posthog-js": "^1.167.0"
|
|
24
23
|
},
|
|
25
24
|
"files": [
|
|
26
25
|
"src/",
|
|
27
26
|
"package.json",
|
|
28
27
|
"README.md"
|
|
29
|
-
]
|
|
28
|
+
],
|
|
29
|
+
"module": "dist/index.mjs"
|
|
30
30
|
}
|
package/src/index.d.ts
CHANGED
|
@@ -1,30 +1,61 @@
|
|
|
1
1
|
declare module 'mem0ai' {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
2
|
+
export interface MemoryOptions {
|
|
3
|
+
user_id?: string;
|
|
4
|
+
agent_id?: string;
|
|
5
|
+
app_id?: string;
|
|
6
|
+
metadata?: Record<string, any>;
|
|
7
|
+
filters?: Record<string, any>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface SearchOptions extends MemoryOptions {
|
|
11
|
+
api_version?: 'v1' | 'v2';
|
|
12
|
+
limit?: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface Memory {
|
|
16
|
+
id: string;
|
|
17
|
+
messages: Array<{ role: string; content: string }>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class MemoryClient {
|
|
21
|
+
constructor(
|
|
22
|
+
apiKey: string,
|
|
23
|
+
host?: string,
|
|
24
|
+
organizationName?: string,
|
|
25
|
+
projectName?: string
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
add(
|
|
29
|
+
messages: string | Array<{ role: string; content: string }>,
|
|
30
|
+
options?: MemoryOptions
|
|
31
|
+
): Promise<Memory>;
|
|
32
|
+
|
|
33
|
+
get(memoryId: string): Promise<Memory>;
|
|
34
|
+
|
|
35
|
+
getAll(options?: MemoryOptions & { api_version?: 'v1' | 'v2' }): Promise<{ results: Memory[] }>;
|
|
36
|
+
|
|
37
|
+
search(query: string, options?: SearchOptions): Promise<{ results: Memory[] }>;
|
|
38
|
+
|
|
39
|
+
delete(memoryId: string): Promise<any>;
|
|
40
|
+
|
|
41
|
+
deleteAll(options?: MemoryOptions): Promise<any>;
|
|
42
|
+
|
|
43
|
+
history(memoryId: string): Promise<any>;
|
|
44
|
+
|
|
45
|
+
users(): Promise<any>;
|
|
46
|
+
|
|
47
|
+
deleteUsers(): Promise<{ message: string }>;
|
|
48
|
+
|
|
49
|
+
private _validateApiKey(): Promise<void>;
|
|
50
|
+
|
|
51
|
+
private _preparePayload(
|
|
52
|
+
messages: string | Array<{ role: string; content: string }>,
|
|
53
|
+
options: MemoryOptions
|
|
54
|
+
): object;
|
|
55
|
+
|
|
56
|
+
private _prepareParams(options: MemoryOptions): object;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { MemoryClient };
|
|
60
|
+
export default MemoryClient;
|
|
61
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,226 +1,219 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { telemetry, captureClientEvent } = require('./telemetry');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @typedef {Object} MemoryOptions
|
|
7
|
-
* @property {string} [user_id]
|
|
8
|
-
*
|
|
9
|
-
* @typedef {Object} SearchOptions
|
|
10
|
-
* @property {string} [user_id]
|
|
11
|
-
* @property {('v1'|'v2')} [api_version]
|
|
12
|
-
*
|
|
13
|
-
* @typedef {Object} Memory
|
|
14
|
-
* @property {string} id
|
|
15
|
-
* @property {Array<{role: string, content: string}>} messages
|
|
16
|
-
*/
|
|
1
|
+
import { telemetry, captureClientEvent } from './telemetry.js';
|
|
2
|
+
import crypto from 'crypto';
|
|
17
3
|
|
|
18
4
|
class APIError extends Error {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @template T
|
|
27
|
-
* @param {(...args: any[]) => Promise<T>} fn
|
|
28
|
-
* @returns {(...args: any[]) => Promise<T>}
|
|
29
|
-
*/
|
|
30
|
-
function apiErrorHandler(fn) {
|
|
31
|
-
return async function (...args) {
|
|
32
|
-
try {
|
|
33
|
-
return await fn.apply(this, args);
|
|
34
|
-
} catch (error) {
|
|
35
|
-
if (error.response) {
|
|
36
|
-
throw new APIError(`API request failed: ${error.response.data}`);
|
|
37
|
-
} else if (error.request) {
|
|
38
|
-
throw new APIError(`Request failed: ${error.message}`);
|
|
39
|
-
} else {
|
|
40
|
-
throw error;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
};
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'APIError';
|
|
8
|
+
}
|
|
44
9
|
}
|
|
45
10
|
|
|
46
11
|
/**
|
|
47
12
|
* MemoryClient for interacting with the mem0ai API
|
|
48
13
|
*/
|
|
49
14
|
class MemoryClient {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} apiKey
|
|
17
|
+
* @param {string} [host]
|
|
18
|
+
* @param {string} [organizationName]
|
|
19
|
+
* @param {string} [projectName]
|
|
20
|
+
*/
|
|
21
|
+
constructor(apiKey, host = 'https://api.mem0.ai', organizationName = null, projectName = null) {
|
|
22
|
+
this.apiKey = apiKey;
|
|
23
|
+
this.host = host;
|
|
24
|
+
this.organizationName = organizationName;
|
|
25
|
+
this.projectName = projectName;
|
|
26
|
+
this.telemetryId = crypto.createHash('md5').update(this.apiKey).digest('hex');
|
|
27
|
+
|
|
28
|
+
this.headers = {
|
|
29
|
+
'Authorization': `Token ${this.apiKey}`,
|
|
30
|
+
'Content-Type': 'application/json'
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
this._validateApiKey();
|
|
34
|
+
|
|
35
|
+
captureClientEvent('init', this, {
|
|
36
|
+
host: this.host,
|
|
37
|
+
organization_name: this.organizationName,
|
|
38
|
+
project_name: this.projectName,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
this._wrapMethods();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
_validateApiKey() {
|
|
45
|
+
if (!this.apiKey) {
|
|
46
|
+
throw new Error('Mem0 API key is required');
|
|
47
|
+
}
|
|
48
|
+
if (typeof this.apiKey !== 'string') {
|
|
49
|
+
throw new Error('Mem0 API key must be a string');
|
|
50
|
+
}
|
|
51
|
+
if (this.apiKey.trim() === '') {
|
|
52
|
+
throw new Error('Mem0 API key cannot be empty');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async _fetchWithErrorHandling(url, options) {
|
|
57
|
+
const response = await fetch(url, options);
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
const errorData = await response.text();
|
|
60
|
+
throw new APIError(`API request failed: ${errorData}`);
|
|
61
|
+
}
|
|
62
|
+
return response.json();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async add(messages, options = {}) {
|
|
66
|
+
options.organization_name = this.organizationName;
|
|
67
|
+
options.project_name = this.projectName;
|
|
68
|
+
const payload = this._preparePayload(messages, options);
|
|
69
|
+
const response = await this._fetchWithErrorHandling(`${this.host}/v1/memories/`, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: this.headers,
|
|
72
|
+
body: JSON.stringify(payload)
|
|
73
|
+
});
|
|
74
|
+
captureClientEvent('add', this, { messages_count: messages.length });
|
|
75
|
+
return response;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async get(memoryId) {
|
|
79
|
+
return this._fetchWithErrorHandling(`${this.host}/v1/memories/${memoryId}/`, {
|
|
80
|
+
headers: this.headers
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async getAll(options = {}) {
|
|
85
|
+
const { api_version, ...otherOptions } = options;
|
|
86
|
+
|
|
87
|
+
otherOptions.organization_name = this.organizationName;
|
|
88
|
+
otherOptions.project_name = this.projectName;
|
|
89
|
+
|
|
90
|
+
if (api_version === 'v2') {
|
|
91
|
+
return this._fetchWithErrorHandling(`${this.host}/v2/memories/`, {
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers: this.headers,
|
|
94
|
+
body: JSON.stringify(otherOptions)
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
const params = new URLSearchParams(this._prepareParams(otherOptions));
|
|
98
|
+
return this._fetchWithErrorHandling(`${this.host}/v1/memories/?${params}`, {
|
|
99
|
+
headers: this.headers
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async search(query, options = {}) {
|
|
105
|
+
const { api_version, ...otherOptions } = options;
|
|
106
|
+
const payload = { query, ...otherOptions };
|
|
107
|
+
payload.organization_name = this.organizationName;
|
|
108
|
+
payload.project_name = this.projectName;
|
|
109
|
+
const endpoint = api_version === 'v2' ? '/v2/memories/search/' : '/v1/memories/search/';
|
|
110
|
+
const response = await this._fetchWithErrorHandling(`${this.host}${endpoint}`, {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
headers: this.headers,
|
|
113
|
+
body: JSON.stringify(payload)
|
|
114
|
+
});
|
|
115
|
+
captureClientEvent('search', this, { query_length: query.length });
|
|
116
|
+
return response;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async delete(memoryId) {
|
|
120
|
+
return this._fetchWithErrorHandling(`${this.host}/v1/memories/${memoryId}/`, {
|
|
121
|
+
method: 'DELETE',
|
|
122
|
+
headers: this.headers
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async deleteAll(options = {}) {
|
|
127
|
+
options.organization_name = this.organizationName;
|
|
128
|
+
options.project_name = this.projectName;
|
|
129
|
+
const params = new URLSearchParams(this._prepareParams(options));
|
|
130
|
+
const response = await this._fetchWithErrorHandling(`${this.host}/v1/memories/?${params}`, {
|
|
131
|
+
method: 'DELETE',
|
|
132
|
+
headers: this.headers
|
|
133
|
+
});
|
|
134
|
+
return response;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async history(memoryId) {
|
|
138
|
+
return this._fetchWithErrorHandling(`${this.host}/v1/memories/${memoryId}/history/`, {
|
|
139
|
+
headers: this.headers
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async users() {
|
|
144
|
+
const params = new URLSearchParams({
|
|
145
|
+
organization_name: this.organizationName,
|
|
146
|
+
project_name: this.projectName
|
|
147
|
+
});
|
|
148
|
+
return this._fetchWithErrorHandling(`${this.host}/v1/entities/?${params}`, {
|
|
149
|
+
headers: this.headers
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async deleteUsers() {
|
|
154
|
+
const entities = await this.users();
|
|
155
|
+
for (const entity of entities.results) {
|
|
156
|
+
const params = {
|
|
157
|
+
organization_name: this.organizationName,
|
|
158
|
+
project_name: this.projectName
|
|
159
|
+
};
|
|
160
|
+
await this.client.delete(`/v1/entities/${entity.type}/${entity.id}/`, { params });
|
|
161
|
+
}
|
|
162
|
+
return { message: "All users, agents, and sessions deleted." };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @param {string|Array<{role: string, content: string}>} messages
|
|
167
|
+
* @param {MemoryOptions} options
|
|
168
|
+
* @returns {Object}
|
|
169
|
+
*/
|
|
170
|
+
_preparePayload(messages, options) {
|
|
171
|
+
const payload = {};
|
|
172
|
+
if (typeof messages === 'string') {
|
|
173
|
+
payload.messages = [{ role: 'user', content: messages }];
|
|
174
|
+
} else if (Array.isArray(messages)) {
|
|
175
|
+
payload.messages = messages;
|
|
176
|
+
}
|
|
177
|
+
return { ...payload, ...options };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* @param {MemoryOptions} options
|
|
182
|
+
* @returns {Object}
|
|
183
|
+
*/
|
|
184
|
+
_prepareParams(options) {
|
|
185
|
+
return Object.fromEntries(Object.entries(options).filter(([_, v]) => v != null));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
_wrapMethods() {
|
|
189
|
+
// Apply error handler and telemetry to methods
|
|
190
|
+
this.add = this._wrapMethod('add', this.add.bind(this));
|
|
191
|
+
this.get = this._wrapMethod('get', this.get.bind(this));
|
|
192
|
+
this.getAll = this._wrapMethod('get_all', this.getAll.bind(this));
|
|
193
|
+
this.search = this._wrapMethod('search', this.search.bind(this));
|
|
194
|
+
this.delete = this._wrapMethod('delete', this.delete.bind(this));
|
|
195
|
+
this.deleteAll = this._wrapMethod('delete_all', this.deleteAll.bind(this));
|
|
196
|
+
this.history = this._wrapMethod('history', this.history.bind(this));
|
|
197
|
+
this.deleteUsers = this._wrapMethod('delete_users', this.deleteUsers.bind(this));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
_wrapMethod(methodName, method) {
|
|
201
|
+
return async (...args) => {
|
|
202
|
+
try {
|
|
203
|
+
const result = await method(...args);
|
|
204
|
+
captureClientEvent(methodName, this, { success: true });
|
|
205
|
+
return result;
|
|
206
|
+
} catch (error) {
|
|
207
|
+
captureClientEvent(methodName, this, { success: false, error: error.message });
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
220
212
|
}
|
|
221
213
|
|
|
222
|
-
|
|
214
|
+
export default MemoryClient;
|
|
223
215
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
216
|
+
// Add a way to manually shutdown telemetry if needed
|
|
217
|
+
MemoryClient.shutdownTelemetry = async () => {
|
|
218
|
+
await telemetry.shutdown();
|
|
219
|
+
};
|
package/src/telemetry.js
CHANGED
|
@@ -1,56 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
const os = require('os');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const fs = require('fs');
|
|
1
|
+
import posthog from 'posthog-js';
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
posthog.init('phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX', { api_host: 'https://us.i.posthog.com' });
|
|
7
4
|
|
|
8
5
|
class AnonymousTelemetry {
|
|
9
|
-
constructor(projectApiKey, host) {
|
|
10
|
-
this.client = new PostHog(projectApiKey, { host });
|
|
11
|
-
if (!MEM0_TELEMETRY) {
|
|
12
|
-
this.client.disable();
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
6
|
|
|
16
7
|
async captureEvent(distinctId, eventName, properties = {}) {
|
|
8
|
+
if (eventName === 'client.init') {
|
|
9
|
+
posthog.identify(distinctId);
|
|
10
|
+
}
|
|
17
11
|
const eventProperties = {
|
|
18
|
-
client_source: '
|
|
19
|
-
client_version: getVersion(),
|
|
20
|
-
node_version: process.version,
|
|
21
|
-
os: process.platform,
|
|
22
|
-
os_version: os.release(),
|
|
23
|
-
os_arch: os.arch(),
|
|
12
|
+
client_source: 'js',
|
|
24
13
|
...properties
|
|
25
14
|
};
|
|
26
15
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
event: eventName,
|
|
31
|
-
properties: eventProperties
|
|
32
|
-
});
|
|
33
|
-
} catch (error) {
|
|
34
|
-
console.error('Error capturing event:', error);
|
|
35
|
-
}
|
|
16
|
+
posthog.capture(eventName, {
|
|
17
|
+
properties: eventProperties
|
|
18
|
+
});
|
|
36
19
|
}
|
|
37
20
|
|
|
38
21
|
async shutdown() {
|
|
39
|
-
|
|
22
|
+
await posthog.shutdown();
|
|
40
23
|
}
|
|
41
24
|
}
|
|
42
25
|
|
|
43
|
-
|
|
44
|
-
const packageJsonPath = path.join(__dirname, '..', 'package.json');
|
|
45
|
-
const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8');
|
|
46
|
-
const packageJson = JSON.parse(packageJsonContent);
|
|
47
|
-
return packageJson.version;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const telemetry = new AnonymousTelemetry(
|
|
51
|
-
'phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX',
|
|
52
|
-
'https://us.i.posthog.com'
|
|
53
|
-
);
|
|
26
|
+
const telemetry = new AnonymousTelemetry();
|
|
54
27
|
|
|
55
28
|
async function captureClientEvent(eventName, instance, additionalData = {}) {
|
|
56
29
|
const eventData = {
|
|
@@ -60,4 +33,4 @@ async function captureClientEvent(eventName, instance, additionalData = {}) {
|
|
|
60
33
|
await telemetry.captureEvent(instance.telemetryId, `client.${eventName}`, eventData);
|
|
61
34
|
}
|
|
62
35
|
|
|
63
|
-
|
|
36
|
+
export { telemetry, captureClientEvent };
|