@usetransactional/memory 1.0.0

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.js ADDED
@@ -0,0 +1,592 @@
1
+ // src/errors.ts
2
+ var MemoryError = class extends Error {
3
+ /** Error code */
4
+ code;
5
+ /** HTTP status code */
6
+ status;
7
+ /** Additional error details */
8
+ details;
9
+ constructor(message, code, status, details) {
10
+ super(message);
11
+ this.name = "MemoryError";
12
+ this.code = code;
13
+ this.status = status;
14
+ this.details = details;
15
+ }
16
+ };
17
+ var AuthenticationError = class extends MemoryError {
18
+ constructor(message = "Invalid or missing API key") {
19
+ super(message, "AUTHENTICATION_ERROR", 401);
20
+ this.name = "AuthenticationError";
21
+ }
22
+ };
23
+ var ValidationError = class extends MemoryError {
24
+ /** Field-level errors */
25
+ fieldErrors;
26
+ constructor(message, fieldErrors) {
27
+ super(message, "VALIDATION_ERROR", 400, { fieldErrors });
28
+ this.name = "ValidationError";
29
+ this.fieldErrors = fieldErrors;
30
+ }
31
+ };
32
+ var NotFoundError = class extends MemoryError {
33
+ /** Resource type */
34
+ resourceType;
35
+ /** Resource ID */
36
+ resourceId;
37
+ constructor(resourceType, resourceId) {
38
+ const message = resourceId ? `${resourceType} with ID '${resourceId}' not found` : `${resourceType} not found`;
39
+ super(message, "NOT_FOUND", 404, { resourceType, resourceId });
40
+ this.name = "NotFoundError";
41
+ this.resourceType = resourceType;
42
+ this.resourceId = resourceId;
43
+ }
44
+ };
45
+ var RateLimitError = class extends MemoryError {
46
+ /** Time to wait before retrying (seconds) */
47
+ retryAfter;
48
+ /** Rate limit */
49
+ limit;
50
+ /** Remaining requests */
51
+ remaining;
52
+ /** Reset timestamp */
53
+ reset;
54
+ constructor(retryAfter, options) {
55
+ super(
56
+ `Rate limit exceeded. Retry after ${retryAfter} seconds.`,
57
+ "RATE_LIMIT_ERROR",
58
+ 429,
59
+ { retryAfter, ...options }
60
+ );
61
+ this.name = "RateLimitError";
62
+ this.retryAfter = retryAfter;
63
+ this.limit = options?.limit;
64
+ this.remaining = options?.remaining;
65
+ this.reset = options?.reset;
66
+ }
67
+ };
68
+ var ServerError = class extends MemoryError {
69
+ constructor(message = "Internal server error", details) {
70
+ super(message, "SERVER_ERROR", 500, details);
71
+ this.name = "ServerError";
72
+ }
73
+ };
74
+ var TimeoutError = class extends MemoryError {
75
+ /** Timeout duration in ms */
76
+ timeout;
77
+ constructor(timeout) {
78
+ super(
79
+ `Request timed out after ${timeout}ms`,
80
+ "TIMEOUT_ERROR",
81
+ 408,
82
+ { timeout }
83
+ );
84
+ this.name = "TimeoutError";
85
+ this.timeout = timeout;
86
+ }
87
+ };
88
+ var NetworkError = class extends MemoryError {
89
+ constructor(message = "Network request failed", details) {
90
+ super(message, "NETWORK_ERROR", 0, details);
91
+ this.name = "NetworkError";
92
+ }
93
+ };
94
+ function parseApiError(status, body) {
95
+ const errorBody = typeof body === "string" ? { message: body } : body;
96
+ const message = errorBody.message || "Unknown error";
97
+ switch (status) {
98
+ case 401:
99
+ return new AuthenticationError(message);
100
+ case 400:
101
+ case 422:
102
+ return new ValidationError(
103
+ message,
104
+ errorBody.errors
105
+ );
106
+ case 404:
107
+ return new NotFoundError("Resource", void 0);
108
+ case 429:
109
+ return new RateLimitError(60);
110
+ // Default to 60 seconds
111
+ case 500:
112
+ case 502:
113
+ case 503:
114
+ case 504:
115
+ return new ServerError(message, errorBody);
116
+ default:
117
+ return new MemoryError(message, "UNKNOWN_ERROR", status, errorBody);
118
+ }
119
+ }
120
+
121
+ // src/client.ts
122
+ var DEFAULT_BASE_URL = "https://api.usetransactional.com";
123
+ var DEFAULT_TIMEOUT = 3e4;
124
+ var DEFAULT_MAX_RETRIES = 3;
125
+ var MemoryClient = class {
126
+ apiKey;
127
+ baseUrl;
128
+ timeout;
129
+ maxRetries;
130
+ customHeaders;
131
+ /** Session operations */
132
+ sessions;
133
+ /** Profile operations */
134
+ profiles;
135
+ /** Graph operations */
136
+ graph;
137
+ /** Ingest operations */
138
+ ingest;
139
+ constructor(config) {
140
+ if (!config.apiKey) {
141
+ throw new AuthenticationError("API key is required");
142
+ }
143
+ this.apiKey = config.apiKey;
144
+ this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
145
+ this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
146
+ this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
147
+ this.customHeaders = config.headers || {};
148
+ this.sessions = new SessionOperations(this);
149
+ this.profiles = new ProfileOperations(this);
150
+ this.graph = new GraphOperations(this);
151
+ this.ingest = new IngestOperations(this);
152
+ }
153
+ // ===========================================
154
+ // HTTP METHODS
155
+ // ===========================================
156
+ /**
157
+ * Make an HTTP request to the API.
158
+ */
159
+ async request(options) {
160
+ const url = `${this.baseUrl}${options.path}`;
161
+ const timeout = options.timeout ?? this.timeout;
162
+ const headers = {
163
+ "X-API-Key": this.apiKey,
164
+ "Content-Type": "application/json",
165
+ "Accept": "application/json",
166
+ ...this.customHeaders,
167
+ ...options.headers
168
+ };
169
+ let lastError = null;
170
+ for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
171
+ try {
172
+ const controller = new AbortController();
173
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
174
+ try {
175
+ const response = await fetch(url, {
176
+ method: options.method,
177
+ headers,
178
+ body: options.body ? JSON.stringify(options.body) : void 0,
179
+ signal: controller.signal
180
+ });
181
+ clearTimeout(timeoutId);
182
+ const text = await response.text();
183
+ let body;
184
+ try {
185
+ body = text ? JSON.parse(text) : {};
186
+ } catch {
187
+ body = { message: text };
188
+ }
189
+ if (!response.ok) {
190
+ const error = parseApiError(response.status, body);
191
+ if (response.status < 500 && response.status !== 429) {
192
+ throw error;
193
+ }
194
+ if (response.status === 429) {
195
+ const retryAfter = parseInt(
196
+ response.headers.get("Retry-After") || "60",
197
+ 10
198
+ );
199
+ if (attempt < this.maxRetries) {
200
+ await this.sleep(retryAfter * 1e3);
201
+ continue;
202
+ }
203
+ throw new RateLimitError(retryAfter);
204
+ }
205
+ lastError = error;
206
+ if (attempt < this.maxRetries) {
207
+ await this.sleep(Math.pow(2, attempt) * 1e3);
208
+ continue;
209
+ }
210
+ throw error;
211
+ }
212
+ const apiResponse = body;
213
+ return apiResponse.data;
214
+ } finally {
215
+ clearTimeout(timeoutId);
216
+ }
217
+ } catch (error) {
218
+ if (error instanceof MemoryError) {
219
+ throw error;
220
+ }
221
+ if (error instanceof Error) {
222
+ if (error.name === "AbortError") {
223
+ throw new TimeoutError(timeout);
224
+ }
225
+ lastError = new NetworkError(error.message);
226
+ }
227
+ if (attempt < this.maxRetries) {
228
+ await this.sleep(Math.pow(2, attempt) * 1e3);
229
+ continue;
230
+ }
231
+ throw lastError || new NetworkError("Request failed");
232
+ }
233
+ }
234
+ throw lastError || new NetworkError("Request failed after retries");
235
+ }
236
+ sleep(ms) {
237
+ return new Promise((resolve) => setTimeout(resolve, ms));
238
+ }
239
+ // ===========================================
240
+ // MEMORY OPERATIONS
241
+ // ===========================================
242
+ /**
243
+ * Add a memory.
244
+ */
245
+ async add(params) {
246
+ return this.request({
247
+ method: "POST",
248
+ path: "/memory/ingest",
249
+ body: {
250
+ content: params.content,
251
+ sessionId: params.sessionId,
252
+ metadata: {
253
+ ...params.metadata,
254
+ userId: params.userId,
255
+ type: params.type
256
+ }
257
+ }
258
+ });
259
+ }
260
+ /**
261
+ * Search memories.
262
+ */
263
+ async search(params) {
264
+ return this.request({
265
+ method: "POST",
266
+ path: params.sessionId ? `/memory/sessions/${params.sessionId}/search` : "/memory/search/global",
267
+ body: {
268
+ query: params.query,
269
+ sessionIds: params.sessionIds,
270
+ userId: params.userId,
271
+ types: params.types,
272
+ strategy: params.strategy,
273
+ threshold: params.threshold,
274
+ limit: params.limit,
275
+ includeRelated: params.includeRelated
276
+ }
277
+ });
278
+ }
279
+ /**
280
+ * Get a specific memory by ID.
281
+ */
282
+ async get(sessionId, memoryId) {
283
+ return this.request({
284
+ method: "GET",
285
+ path: `/memory/sessions/${sessionId}/entities/${memoryId}`
286
+ });
287
+ }
288
+ /**
289
+ * Update a memory.
290
+ */
291
+ async update(sessionId, memoryId, params) {
292
+ return this.request({
293
+ method: "PATCH",
294
+ path: `/memory/sessions/${sessionId}/entities/${memoryId}`,
295
+ body: params
296
+ });
297
+ }
298
+ /**
299
+ * Delete a memory.
300
+ */
301
+ async delete(sessionId, memoryId) {
302
+ await this.request({
303
+ method: "DELETE",
304
+ path: `/memory/sessions/${sessionId}/entities/${memoryId}`
305
+ });
306
+ }
307
+ /**
308
+ * Get context for LLM prompts.
309
+ */
310
+ async getContext(params) {
311
+ const queryParams = new URLSearchParams();
312
+ if (params.query) queryParams.set("query", params.query);
313
+ if (params.maxTokens) queryParams.set("maxTokens", params.maxTokens.toString());
314
+ if (params.includeProfile !== void 0)
315
+ queryParams.set("includeProfile", params.includeProfile.toString());
316
+ if (params.includeFacts !== void 0)
317
+ queryParams.set("includeFacts", params.includeFacts.toString());
318
+ if (params.includePreferences !== void 0)
319
+ queryParams.set("includePreferences", params.includePreferences.toString());
320
+ const path = params.sessionId ? `/memory/sessions/${params.sessionId}/context` : `/memory/profiles/${params.userId}/context`;
321
+ return this.request({
322
+ method: "GET",
323
+ path: `${path}?${queryParams.toString()}`
324
+ });
325
+ }
326
+ /**
327
+ * Get job status.
328
+ */
329
+ async getJobStatus(jobId) {
330
+ return this.request({
331
+ method: "GET",
332
+ path: `/memory/jobs/${jobId}`
333
+ });
334
+ }
335
+ };
336
+ var SessionOperations = class {
337
+ constructor(client) {
338
+ this.client = client;
339
+ }
340
+ /**
341
+ * Create a new session.
342
+ */
343
+ async create(params) {
344
+ return this.client.request({
345
+ method: "POST",
346
+ path: "/memory/sessions",
347
+ body: params
348
+ });
349
+ }
350
+ /**
351
+ * Get a session by ID.
352
+ */
353
+ async get(sessionId) {
354
+ return this.client.request({
355
+ method: "GET",
356
+ path: `/memory/sessions/${sessionId}`
357
+ });
358
+ }
359
+ /**
360
+ * List sessions.
361
+ */
362
+ async list(params) {
363
+ const queryParams = new URLSearchParams();
364
+ if (params?.status) queryParams.set("status", params.status);
365
+ if (params?.agentId) queryParams.set("agentId", params.agentId);
366
+ if (params?.userId) queryParams.set("userId", params.userId);
367
+ if (params?.search) queryParams.set("search", params.search);
368
+ if (params?.page) queryParams.set("page", params.page.toString());
369
+ if (params?.limit) queryParams.set("limit", params.limit.toString());
370
+ return this.client.request({
371
+ method: "GET",
372
+ path: `/memory/sessions?${queryParams.toString()}`
373
+ });
374
+ }
375
+ /**
376
+ * Update a session.
377
+ */
378
+ async update(sessionId, params) {
379
+ return this.client.request({
380
+ method: "PATCH",
381
+ path: `/memory/sessions/${sessionId}`,
382
+ body: params
383
+ });
384
+ }
385
+ /**
386
+ * Delete a session.
387
+ */
388
+ async delete(sessionId) {
389
+ await this.client.request({
390
+ method: "DELETE",
391
+ path: `/memory/sessions/${sessionId}`
392
+ });
393
+ }
394
+ };
395
+ var ProfileOperations = class {
396
+ constructor(client) {
397
+ this.client = client;
398
+ }
399
+ /**
400
+ * Get a user profile.
401
+ */
402
+ async get(userId) {
403
+ return this.client.request({
404
+ method: "GET",
405
+ path: `/memory/profiles/${userId}`
406
+ });
407
+ }
408
+ /**
409
+ * Create or update a user profile.
410
+ */
411
+ async upsert(userId, params) {
412
+ return this.client.request({
413
+ method: "POST",
414
+ path: `/memory/profiles/${userId}`,
415
+ body: params
416
+ });
417
+ }
418
+ /**
419
+ * Delete a user profile.
420
+ */
421
+ async delete(userId) {
422
+ await this.client.request({
423
+ method: "DELETE",
424
+ path: `/memory/profiles/${userId}`
425
+ });
426
+ }
427
+ };
428
+ var GraphOperations = class {
429
+ constructor(client) {
430
+ this.client = client;
431
+ }
432
+ /**
433
+ * Get the knowledge graph.
434
+ */
435
+ async get(params) {
436
+ const queryParams = new URLSearchParams();
437
+ if (params?.centerEntityId)
438
+ queryParams.set("centerEntityId", params.centerEntityId);
439
+ if (params?.depth) queryParams.set("depth", params.depth.toString());
440
+ if (params?.entityTypes)
441
+ queryParams.set("entityTypes", params.entityTypes.join(","));
442
+ if (params?.edgeTypes)
443
+ queryParams.set("edgeTypes", params.edgeTypes.join(","));
444
+ if (params?.minWeight)
445
+ queryParams.set("minWeight", params.minWeight.toString());
446
+ if (params?.limit) queryParams.set("limit", params.limit.toString());
447
+ const path = params?.sessionId ? `/memory/sessions/${params.sessionId}/graph` : "/memory/graph";
448
+ return this.client.request({
449
+ method: "GET",
450
+ path: `${path}?${queryParams.toString()}`
451
+ });
452
+ }
453
+ /**
454
+ * Traverse the graph from a starting entity.
455
+ */
456
+ async traverse(params) {
457
+ const queryParams = new URLSearchParams();
458
+ queryParams.set("startEntityId", params.startEntityId);
459
+ if (params.depth) queryParams.set("depth", params.depth.toString());
460
+ if (params.direction) queryParams.set("direction", params.direction);
461
+ if (params.entityTypes)
462
+ queryParams.set("entityTypes", params.entityTypes.join(","));
463
+ if (params.edgeTypes)
464
+ queryParams.set("edgeTypes", params.edgeTypes.join(","));
465
+ if (params.minWeight)
466
+ queryParams.set("minWeight", params.minWeight.toString());
467
+ if (params.limit) queryParams.set("limit", params.limit.toString());
468
+ return this.client.request({
469
+ method: "GET",
470
+ path: `/memory/graph/traverse?${queryParams.toString()}`
471
+ });
472
+ }
473
+ };
474
+ var IngestOperations = class {
475
+ constructor(client) {
476
+ this.client = client;
477
+ }
478
+ /**
479
+ * Ingest URL content.
480
+ */
481
+ async url(params) {
482
+ return this.client.request({
483
+ method: "POST",
484
+ path: "/memory/ingest/url",
485
+ body: params
486
+ });
487
+ }
488
+ /**
489
+ * Ingest PDF content.
490
+ */
491
+ async pdf(params) {
492
+ const formData = new FormData();
493
+ if (Buffer.isBuffer(params.file)) {
494
+ const blob = new Blob([params.file], { type: "application/pdf" });
495
+ formData.append("file", blob, params.filename);
496
+ } else {
497
+ formData.append("file", params.file, params.filename);
498
+ }
499
+ const options = {
500
+ sessionId: params.sessionId,
501
+ userId: params.userId,
502
+ metadata: params.metadata,
503
+ extractEntities: params.options?.extractEntities,
504
+ generateEmbeddings: params.options?.generateEmbeddings,
505
+ ocrFallback: params.options?.ocrFallback
506
+ };
507
+ formData.append("options", JSON.stringify(options));
508
+ const url = `${this.client.baseUrl}/memory/ingest/pdf`;
509
+ const response = await fetch(url, {
510
+ method: "POST",
511
+ headers: {
512
+ "X-API-Key": this.client.apiKey
513
+ },
514
+ body: formData
515
+ });
516
+ if (!response.ok) {
517
+ const text = await response.text();
518
+ let body;
519
+ try {
520
+ body = JSON.parse(text);
521
+ } catch {
522
+ body = { message: text };
523
+ }
524
+ throw parseApiError(response.status, body);
525
+ }
526
+ const result = await response.json();
527
+ return result.data;
528
+ }
529
+ /**
530
+ * Ingest text content.
531
+ */
532
+ async text(params) {
533
+ return this.client.request({
534
+ method: "POST",
535
+ path: "/memory/ingest",
536
+ body: {
537
+ content: params.content,
538
+ contentType: params.contentType,
539
+ sessionId: params.sessionId,
540
+ metadata: params.metadata
541
+ }
542
+ });
543
+ }
544
+ };
545
+
546
+ // src/types.ts
547
+ var MemoryEntityType = /* @__PURE__ */ ((MemoryEntityType2) => {
548
+ MemoryEntityType2["USER"] = "user";
549
+ MemoryEntityType2["FACT"] = "fact";
550
+ MemoryEntityType2["TOPIC"] = "topic";
551
+ MemoryEntityType2["PREFERENCE"] = "preference";
552
+ MemoryEntityType2["EVENT"] = "event";
553
+ MemoryEntityType2["MESSAGE"] = "message";
554
+ MemoryEntityType2["SUMMARY"] = "summary";
555
+ MemoryEntityType2["ORGANIZATION"] = "organization";
556
+ return MemoryEntityType2;
557
+ })(MemoryEntityType || {});
558
+ var MemoryEdgeType = /* @__PURE__ */ ((MemoryEdgeType2) => {
559
+ MemoryEdgeType2["PREFERS"] = "prefers";
560
+ MemoryEdgeType2["MENTIONED"] = "mentioned";
561
+ MemoryEdgeType2["DISCUSSED"] = "discussed";
562
+ MemoryEdgeType2["ASKED_ABOUT"] = "asked_about";
563
+ MemoryEdgeType2["RELATES_TO"] = "relates_to";
564
+ MemoryEdgeType2["FOLLOWS_UP"] = "follows_up";
565
+ MemoryEdgeType2["SUMMARIZES"] = "summarizes";
566
+ MemoryEdgeType2["EXTRACTED_FROM"] = "extracted_from";
567
+ MemoryEdgeType2["WORKS_AT"] = "works_at";
568
+ MemoryEdgeType2["INTERESTED_IN"] = "interested_in";
569
+ return MemoryEdgeType2;
570
+ })(MemoryEdgeType || {});
571
+ var MemoryFactSource = /* @__PURE__ */ ((MemoryFactSource2) => {
572
+ MemoryFactSource2["EXTRACTED"] = "extracted";
573
+ MemoryFactSource2["EXPLICIT"] = "explicit";
574
+ MemoryFactSource2["INFERRED"] = "inferred";
575
+ return MemoryFactSource2;
576
+ })(MemoryFactSource || {});
577
+ var MemorySessionStatus = /* @__PURE__ */ ((MemorySessionStatus2) => {
578
+ MemorySessionStatus2["ACTIVE"] = "ACTIVE";
579
+ MemorySessionStatus2["EXPIRED"] = "EXPIRED";
580
+ MemorySessionStatus2["DELETED"] = "DELETED";
581
+ return MemorySessionStatus2;
582
+ })(MemorySessionStatus || {});
583
+ var MemoryMessageRole = /* @__PURE__ */ ((MemoryMessageRole2) => {
584
+ MemoryMessageRole2["USER"] = "user";
585
+ MemoryMessageRole2["ASSISTANT"] = "assistant";
586
+ MemoryMessageRole2["SYSTEM"] = "system";
587
+ return MemoryMessageRole2;
588
+ })(MemoryMessageRole || {});
589
+
590
+ export { AuthenticationError, MemoryClient, MemoryEdgeType, MemoryEntityType, MemoryError, MemoryFactSource, MemoryMessageRole, MemorySessionStatus, NetworkError, NotFoundError, RateLimitError, ServerError, TimeoutError, ValidationError };
591
+ //# sourceMappingURL=index.js.map
592
+ //# sourceMappingURL=index.js.map