@ai.ntellect/core 0.6.17 → 0.6.19
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/.mocharc.json +1 -2
- package/README.md +123 -178
- package/dist/graph/controller.js +29 -6
- package/dist/graph/index.js +302 -62
- package/dist/index.js +21 -6
- package/dist/interfaces/index.js +15 -0
- package/dist/modules/agenda/adapters/node-cron/index.js +29 -0
- package/dist/modules/agenda/index.js +140 -0
- package/dist/{services/embedding.js → modules/embedding/adapters/ai/index.js} +24 -7
- package/dist/modules/embedding/index.js +59 -0
- package/dist/modules/memory/adapters/in-memory/index.js +210 -0
- package/dist/{memory → modules/memory}/adapters/meilisearch/index.js +97 -2
- package/dist/{memory → modules/memory}/adapters/redis/index.js +77 -15
- package/dist/modules/memory/index.js +103 -0
- package/dist/utils/{stringifiy-zod-schema.js → generate-action-schema.js} +5 -5
- package/graph/controller.ts +37 -13
- package/graph/index.ts +348 -73
- package/index.ts +24 -6
- package/interfaces/index.ts +346 -27
- package/modules/agenda/adapters/node-cron/index.ts +25 -0
- package/modules/agenda/index.ts +159 -0
- package/modules/embedding/adapters/ai/index.ts +42 -0
- package/modules/embedding/index.ts +45 -0
- package/modules/memory/adapters/in-memory/index.ts +203 -0
- package/{memory → modules/memory}/adapters/meilisearch/index.ts +114 -12
- package/modules/memory/adapters/redis/index.ts +164 -0
- package/modules/memory/index.ts +93 -0
- package/package.json +3 -1
- package/test/graph/index.test.ts +646 -0
- package/test/modules/agenda/node-cron.test.ts +286 -0
- package/test/modules/embedding/ai.test.ts +78 -0
- package/test/modules/memory/adapters/in-memory.test.ts +153 -0
- package/test/{memory → modules/memory}/adapters/meilisearch.test.ts +79 -75
- package/test/modules/memory/adapters/redis.test.ts +169 -0
- package/test/modules/memory/base.test.ts +230 -0
- package/test/services/agenda.test.ts +279 -280
- package/types/index.ts +82 -203
- package/utils/{stringifiy-zod-schema.ts → generate-action-schema.ts} +3 -3
- package/app/README.md +0 -36
- package/app/app/favicon.ico +0 -0
- package/app/app/globals.css +0 -21
- package/app/app/gun.ts +0 -0
- package/app/app/layout.tsx +0 -18
- package/app/app/page.tsx +0 -321
- package/app/eslint.config.mjs +0 -16
- package/app/next.config.ts +0 -7
- package/app/package-lock.json +0 -5912
- package/app/package.json +0 -31
- package/app/pnpm-lock.yaml +0 -4031
- package/app/postcss.config.mjs +0 -8
- package/app/public/file.svg +0 -1
- package/app/public/globe.svg +0 -1
- package/app/public/next.svg +0 -1
- package/app/public/vercel.svg +0 -1
- package/app/public/window.svg +0 -1
- package/app/tailwind.config.ts +0 -18
- package/app/tsconfig.json +0 -27
- package/dist/memory/index.js +0 -9
- package/dist/services/agenda.js +0 -115
- package/dist/services/queue.js +0 -142
- package/dist/utils/experimental-graph-rag.js +0 -152
- package/dist/utils/generate-object.js +0 -111
- package/dist/utils/inject-actions.js +0 -16
- package/dist/utils/queue-item-transformer.js +0 -24
- package/dist/utils/sanitize-results.js +0 -60
- package/memory/adapters/redis/index.ts +0 -103
- package/memory/index.ts +0 -22
- package/services/agenda.ts +0 -118
- package/services/embedding.ts +0 -26
- package/services/queue.ts +0 -145
- package/test/memory/adapters/redis.test.ts +0 -159
- package/test/memory/base.test.ts +0 -225
- package/test/services/queue.test.ts +0 -286
- package/utils/experimental-graph-rag.ts +0 -170
- package/utils/generate-object.ts +0 -117
- package/utils/inject-actions.ts +0 -19
- package/utils/queue-item-transformer.ts +0 -38
- package/utils/sanitize-results.ts +0 -66
@@ -0,0 +1,203 @@
|
|
1
|
+
import { ICronJob, IMemoryAdapter } from "interfaces";
|
2
|
+
import { BaseMemoryType, CreateMemoryInput, ScheduledRequest } from "types";
|
3
|
+
|
4
|
+
/**
|
5
|
+
* @module InMemoryAdapter
|
6
|
+
* @description In-memory implementation of the memory storage adapter.
|
7
|
+
* Provides a simple Map-based storage solution
|
8
|
+
* @implements {IMemoryAdapter}
|
9
|
+
*/
|
10
|
+
export class InMemoryAdapter implements IMemoryAdapter {
|
11
|
+
/** Internal storage using Map structure for jobs and requests */
|
12
|
+
private jobs: Map<string, ICronJob>;
|
13
|
+
/** Internal storage using Map structure for requests */
|
14
|
+
private requests: Map<string, ScheduledRequest>;
|
15
|
+
/** Internal storage using Map structure */
|
16
|
+
private storage: Map<string, BaseMemoryType[]>;
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Creates an instance of InMemoryAdapter
|
20
|
+
*/
|
21
|
+
constructor() {
|
22
|
+
this.storage = new Map();
|
23
|
+
this.jobs = new Map();
|
24
|
+
this.requests = new Map();
|
25
|
+
}
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Initializes storage for a room
|
29
|
+
* @param {string} roomId - Room identifier
|
30
|
+
* @returns {Promise<void>}
|
31
|
+
*/
|
32
|
+
async init(roomId: string): Promise<void> {
|
33
|
+
if (!this.storage.has(roomId)) {
|
34
|
+
this.storage.set(roomId, []);
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* Creates a new memory entry
|
40
|
+
* @param {CreateMemoryInput & { embedding?: number[] }} input - Memory data with optional embedding
|
41
|
+
* @returns {Promise<BaseMemoryType | undefined>} Created memory or existing memory if duplicate
|
42
|
+
*/
|
43
|
+
async createMemory(
|
44
|
+
input: CreateMemoryInput & { embedding?: number[] }
|
45
|
+
): Promise<BaseMemoryType | undefined> {
|
46
|
+
await this.init(input.roomId);
|
47
|
+
|
48
|
+
// Check if memory already exists
|
49
|
+
const memories = this.storage.get(input.roomId) || [];
|
50
|
+
const existingMemory = memories.find((m) => m.data === input.data);
|
51
|
+
if (existingMemory) {
|
52
|
+
return existingMemory;
|
53
|
+
}
|
54
|
+
|
55
|
+
// Create new memory
|
56
|
+
const memory: BaseMemoryType = {
|
57
|
+
id: input.id || crypto.randomUUID(),
|
58
|
+
data: input.data,
|
59
|
+
embedding: input.embedding,
|
60
|
+
roomId: input.roomId,
|
61
|
+
createdAt: new Date(),
|
62
|
+
};
|
63
|
+
|
64
|
+
memories.push(memory);
|
65
|
+
this.storage.set(input.roomId, memories);
|
66
|
+
return memory;
|
67
|
+
}
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Retrieves a memory by ID and room ID
|
71
|
+
* @param {string} id - Memory identifier
|
72
|
+
* @param {string} roomId - Room identifier
|
73
|
+
* @returns {Promise<BaseMemoryType | null>} Memory entry or null if not found
|
74
|
+
*/
|
75
|
+
async getMemoryById(
|
76
|
+
id: string,
|
77
|
+
roomId: string
|
78
|
+
): Promise<BaseMemoryType | null> {
|
79
|
+
const memories = this.storage.get(roomId) || [];
|
80
|
+
return memories.find((m) => m.id === id) || null;
|
81
|
+
}
|
82
|
+
|
83
|
+
/**
|
84
|
+
* Searches for memories based on query and options
|
85
|
+
* @param {string} query - Search query
|
86
|
+
* @param {Object} options - Search options
|
87
|
+
* @param {string} options.roomId - Room identifier
|
88
|
+
* @param {number} [options.limit] - Maximum number of results
|
89
|
+
* @returns {Promise<BaseMemoryType[]>} Array of matching memories
|
90
|
+
*/
|
91
|
+
async getMemoryByIndex(
|
92
|
+
query: string,
|
93
|
+
options: { roomId: string; limit?: number }
|
94
|
+
): Promise<BaseMemoryType[]> {
|
95
|
+
const memories = this.storage.get(options.roomId) || [];
|
96
|
+
const filtered = memories.filter((m) => m.data.includes(query));
|
97
|
+
return filtered.slice(0, options.limit || filtered.length);
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* Retrieves all memories for a room
|
102
|
+
* @param {string} roomId - Room identifier
|
103
|
+
* @returns {Promise<BaseMemoryType[]>} Array of all memories
|
104
|
+
*/
|
105
|
+
async getAllMemories(roomId: string): Promise<BaseMemoryType[]> {
|
106
|
+
return this.storage.get(roomId) || [];
|
107
|
+
}
|
108
|
+
|
109
|
+
/**
|
110
|
+
* Deletes a specific memory
|
111
|
+
* @param {string} id - Memory identifier
|
112
|
+
* @param {string} roomId - Room identifier
|
113
|
+
* @returns {Promise<void>}
|
114
|
+
*/
|
115
|
+
async clearMemoryById(id: string, roomId: string): Promise<void> {
|
116
|
+
const memories = this.storage.get(roomId) || [];
|
117
|
+
const filtered = memories.filter((m) => m.id !== id);
|
118
|
+
this.storage.set(roomId, filtered);
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* Clears all memories across all rooms
|
123
|
+
* @returns {Promise<void>}
|
124
|
+
*/
|
125
|
+
async clearAllMemories(): Promise<void> {
|
126
|
+
this.storage.clear();
|
127
|
+
this.jobs.clear();
|
128
|
+
this.requests.clear();
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Saves a job to the internal storage
|
133
|
+
* @param {string} id - Job identifier
|
134
|
+
* @param {ICronJob} job - Job data
|
135
|
+
* @returns {Promise<void>}
|
136
|
+
*/
|
137
|
+
async saveJob(id: string, job: ICronJob): Promise<void> {
|
138
|
+
this.jobs.set(id, job);
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* Saves a request to the internal storage
|
143
|
+
* @param {string} id - Request identifier
|
144
|
+
* @param {ScheduledRequest} request - Request data
|
145
|
+
* @returns {Promise<void>}
|
146
|
+
*/
|
147
|
+
async saveRequest(id: string, request: ScheduledRequest): Promise<void> {
|
148
|
+
this.requests.set(id, request);
|
149
|
+
}
|
150
|
+
|
151
|
+
/**
|
152
|
+
* Retrieves a job by ID
|
153
|
+
* @param {string} id - Job identifier
|
154
|
+
* @returns {Promise<ICronJob | undefined>} Job data or undefined if not found
|
155
|
+
*/
|
156
|
+
async getJob(id: string): Promise<ICronJob | undefined> {
|
157
|
+
return this.jobs.get(id);
|
158
|
+
}
|
159
|
+
|
160
|
+
/**
|
161
|
+
* Retrieves a request by ID
|
162
|
+
* @param {string} id - Request identifier
|
163
|
+
* @returns {Promise<ScheduledRequest | undefined>} Request data or undefined if not found
|
164
|
+
*/
|
165
|
+
async getRequest(id: string): Promise<ScheduledRequest | undefined> {
|
166
|
+
return this.requests.get(id);
|
167
|
+
}
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Deletes a job by ID
|
171
|
+
* @param {string} id - Job identifier
|
172
|
+
* @returns {Promise<void>}
|
173
|
+
*/
|
174
|
+
async deleteJob(id: string): Promise<void> {
|
175
|
+
this.jobs.delete(id);
|
176
|
+
}
|
177
|
+
|
178
|
+
/**
|
179
|
+
* Deletes a request by ID
|
180
|
+
* @param {string} id - Request identifier
|
181
|
+
* @returns {Promise<void>}
|
182
|
+
*/
|
183
|
+
async deleteRequest(id: string): Promise<void> {
|
184
|
+
this.requests.delete(id);
|
185
|
+
}
|
186
|
+
|
187
|
+
/**
|
188
|
+
* Retrieves all requests
|
189
|
+
* @returns {Promise<ScheduledRequest[]>} Array of all requests
|
190
|
+
*/
|
191
|
+
async getAllRequests(): Promise<ScheduledRequest[]> {
|
192
|
+
return Array.from(this.requests.values());
|
193
|
+
}
|
194
|
+
|
195
|
+
/**
|
196
|
+
* Clears all jobs and requests
|
197
|
+
* @returns {Promise<void>}
|
198
|
+
*/
|
199
|
+
async clear(): Promise<void> {
|
200
|
+
this.jobs.clear();
|
201
|
+
this.requests.clear();
|
202
|
+
}
|
203
|
+
}
|
@@ -1,12 +1,27 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
CreateMemoryInput,
|
4
|
-
MeilisearchConfig,
|
5
|
-
} from "../../../types";
|
1
|
+
import { IMemoryAdapter } from "interfaces";
|
2
|
+
import { BaseMemoryType, CreateMemoryInput, MeilisearchConfig } from "types";
|
6
3
|
|
7
|
-
|
4
|
+
/**
|
5
|
+
* @module MeilisearchAdapter
|
6
|
+
* @description Adapter implementation for Meilisearch as a memory storage solution.
|
7
|
+
* Provides integration with Meilisearch for storing and retrieving memory entries.
|
8
|
+
* @implements {IMemoryAdapter}
|
9
|
+
*/
|
10
|
+
export class MeilisearchAdapter implements IMemoryAdapter {
|
11
|
+
/**
|
12
|
+
* Creates an instance of MeilisearchAdapter
|
13
|
+
* @param {MeilisearchConfig} config - Configuration for Meilisearch connection
|
14
|
+
*/
|
8
15
|
constructor(private readonly config: MeilisearchConfig) {}
|
9
16
|
|
17
|
+
/**
|
18
|
+
* Makes an HTTP request to the Meilisearch API
|
19
|
+
* @private
|
20
|
+
* @param {string} path - API endpoint path
|
21
|
+
* @param {RequestInit} [options] - Fetch request options
|
22
|
+
* @returns {Promise<any>} Response data
|
23
|
+
* @throws {Error} If the request fails
|
24
|
+
*/
|
10
25
|
private async makeRequest(path: string, options?: RequestInit) {
|
11
26
|
try {
|
12
27
|
const url = `${this.config.host}${path}`;
|
@@ -37,7 +52,13 @@ export class MeilisearchAdapter {
|
|
37
52
|
}
|
38
53
|
}
|
39
54
|
|
40
|
-
|
55
|
+
/**
|
56
|
+
* Initializes a storage index for a room
|
57
|
+
* @private
|
58
|
+
* @param {string} roomId - Room identifier to create index for
|
59
|
+
* @returns {Promise<void>}
|
60
|
+
*/
|
61
|
+
private async initializeStorage(roomId: string): Promise<void> {
|
41
62
|
try {
|
42
63
|
let indexExists = false;
|
43
64
|
|
@@ -82,7 +103,14 @@ export class MeilisearchAdapter {
|
|
82
103
|
}
|
83
104
|
}
|
84
105
|
|
85
|
-
|
106
|
+
/**
|
107
|
+
* Adds documents to the Meilisearch index
|
108
|
+
* @private
|
109
|
+
* @param {BaseMemoryType[]} documents - Documents to add
|
110
|
+
* @param {string} roomId - Room identifier
|
111
|
+
* @returns {Promise<void>}
|
112
|
+
*/
|
113
|
+
private async addDocuments(
|
86
114
|
documents: BaseMemoryType[],
|
87
115
|
roomId: string
|
88
116
|
): Promise<void> {
|
@@ -91,13 +119,24 @@ export class MeilisearchAdapter {
|
|
91
119
|
body: JSON.stringify(documents),
|
92
120
|
});
|
93
121
|
}
|
94
|
-
|
122
|
+
|
123
|
+
/**
|
124
|
+
* Deletes a storage index for a room
|
125
|
+
* @private
|
126
|
+
* @param {string} roomId - Room identifier
|
127
|
+
* @returns {Promise<void>}
|
128
|
+
*/
|
129
|
+
private async deleteStorage(roomId: string): Promise<void> {
|
95
130
|
await this.makeRequest(`/indexes/${roomId}`, {
|
96
131
|
method: "DELETE",
|
97
132
|
});
|
98
133
|
}
|
99
134
|
|
100
|
-
|
135
|
+
/**
|
136
|
+
* Initializes the adapter for a specific room
|
137
|
+
* @param {string} roomId - Room identifier
|
138
|
+
* @returns {Promise<void>}
|
139
|
+
*/
|
101
140
|
async init(roomId: string): Promise<void> {
|
102
141
|
try {
|
103
142
|
// Initialize the default "memories" index
|
@@ -110,7 +149,17 @@ export class MeilisearchAdapter {
|
|
110
149
|
}
|
111
150
|
}
|
112
151
|
|
113
|
-
|
152
|
+
/**
|
153
|
+
* Performs a search in the Meilisearch index
|
154
|
+
* @private
|
155
|
+
* @param {string} query - Search query
|
156
|
+
* @param {string} roomId - Room identifier
|
157
|
+
* @param {Object} [options] - Search options
|
158
|
+
* @param {number} [options.limit] - Maximum number of results
|
159
|
+
* @param {number} [options.threshold] - Minimum score threshold
|
160
|
+
* @returns {Promise<SearchResult[]>} Search results
|
161
|
+
*/
|
162
|
+
private async search(
|
114
163
|
query: string,
|
115
164
|
roomId: string,
|
116
165
|
options?: { limit?: number; threshold?: number }
|
@@ -123,6 +172,10 @@ export class MeilisearchAdapter {
|
|
123
172
|
}),
|
124
173
|
});
|
125
174
|
|
175
|
+
if (!searchResults.hits) {
|
176
|
+
return [];
|
177
|
+
}
|
178
|
+
|
126
179
|
return searchResults.hits.map((hit: any) => ({
|
127
180
|
document: {
|
128
181
|
id: hit.id,
|
@@ -135,17 +188,30 @@ export class MeilisearchAdapter {
|
|
135
188
|
}));
|
136
189
|
}
|
137
190
|
|
191
|
+
/**
|
192
|
+
* Creates a new memory entry
|
193
|
+
* @param {CreateMemoryInput & { embedding?: number[] }} input - Memory data with optional embedding
|
194
|
+
* @returns {Promise<BaseMemoryType | undefined>} Created memory or undefined
|
195
|
+
*/
|
138
196
|
async createMemory(
|
139
197
|
input: CreateMemoryInput & { embedding?: number[] }
|
140
198
|
): Promise<BaseMemoryType | undefined> {
|
141
199
|
// Initialize storage for this roomId if needed
|
142
200
|
await this.initializeStorage(input.roomId);
|
143
201
|
|
202
|
+
// Check if the memory already exists
|
203
|
+
const existingMemory = await this.search(input.data, input.roomId, {
|
204
|
+
limit: 1,
|
205
|
+
});
|
206
|
+
if (existingMemory.length > 0) {
|
207
|
+
return existingMemory[0].document;
|
208
|
+
}
|
209
|
+
|
144
210
|
// If not found, create new memory
|
145
211
|
const memory: BaseMemoryType = {
|
146
212
|
id: input.id || crypto.randomUUID(),
|
147
213
|
data: input.data,
|
148
|
-
embedding: input.embedding
|
214
|
+
embedding: input.embedding,
|
149
215
|
roomId: input.roomId,
|
150
216
|
createdAt: new Date(),
|
151
217
|
};
|
@@ -154,6 +220,12 @@ export class MeilisearchAdapter {
|
|
154
220
|
return memory;
|
155
221
|
}
|
156
222
|
|
223
|
+
/**
|
224
|
+
* Retrieves a memory by ID and room ID
|
225
|
+
* @param {string} id - Memory identifier
|
226
|
+
* @param {string} roomId - Room identifier
|
227
|
+
* @returns {Promise<BaseMemoryType | null>} Memory entry or null if not found
|
228
|
+
*/
|
157
229
|
async getMemoryById(
|
158
230
|
id: string,
|
159
231
|
roomId: string
|
@@ -176,6 +248,14 @@ export class MeilisearchAdapter {
|
|
176
248
|
}
|
177
249
|
}
|
178
250
|
|
251
|
+
/**
|
252
|
+
* Searches for memories based on query and options
|
253
|
+
* @param {string} query - Search query
|
254
|
+
* @param {Object} options - Search options
|
255
|
+
* @param {string} options.roomId - Room identifier
|
256
|
+
* @param {number} [options.limit] - Maximum number of results
|
257
|
+
* @returns {Promise<BaseMemoryType[]>} Array of matching memories
|
258
|
+
*/
|
179
259
|
async getMemoryByIndex(
|
180
260
|
query: string,
|
181
261
|
options: { roomId: string; limit?: number }
|
@@ -194,6 +274,11 @@ export class MeilisearchAdapter {
|
|
194
274
|
}));
|
195
275
|
}
|
196
276
|
|
277
|
+
/**
|
278
|
+
* Retrieves all memories for a room
|
279
|
+
* @param {string} roomId - Room identifier
|
280
|
+
* @returns {Promise<BaseMemoryType[]>} Array of all memories
|
281
|
+
*/
|
197
282
|
async getAllMemories(roomId: string): Promise<BaseMemoryType[]> {
|
198
283
|
const results = await this.makeRequest(`/indexes/${roomId}/documents`);
|
199
284
|
if (results.total === 0) {
|
@@ -209,6 +294,12 @@ export class MeilisearchAdapter {
|
|
209
294
|
}));
|
210
295
|
}
|
211
296
|
|
297
|
+
/**
|
298
|
+
* Deletes a specific memory
|
299
|
+
* @param {string} id - Memory identifier
|
300
|
+
* @param {string} roomId - Room identifier
|
301
|
+
* @returns {Promise<void>}
|
302
|
+
*/
|
212
303
|
async clearMemoryById(id: string, roomId: string): Promise<void> {
|
213
304
|
try {
|
214
305
|
// Ensure the index exists before attempting to delete
|
@@ -230,6 +321,10 @@ export class MeilisearchAdapter {
|
|
230
321
|
}
|
231
322
|
}
|
232
323
|
|
324
|
+
/**
|
325
|
+
* Clears all memories across all rooms
|
326
|
+
* @returns {Promise<void>}
|
327
|
+
*/
|
233
328
|
async clearAllMemories(): Promise<void> {
|
234
329
|
try {
|
235
330
|
// Get all indexes
|
@@ -248,8 +343,15 @@ export class MeilisearchAdapter {
|
|
248
343
|
}
|
249
344
|
}
|
250
345
|
|
346
|
+
/**
|
347
|
+
* @interface SearchResult
|
348
|
+
* @description Interface for search results from Meilisearch
|
349
|
+
*/
|
251
350
|
interface SearchResult {
|
351
|
+
/** The matched document */
|
252
352
|
document?: any;
|
353
|
+
/** Relevance score of the match */
|
253
354
|
score?: number;
|
355
|
+
/** Array of additional results */
|
254
356
|
results?: any[];
|
255
357
|
}
|
@@ -0,0 +1,164 @@
|
|
1
|
+
import { IMemoryAdapter } from "interfaces";
|
2
|
+
import { createClient } from "redis";
|
3
|
+
import { BaseMemoryType, CreateMemoryInput } from "types";
|
4
|
+
|
5
|
+
/**
|
6
|
+
* @module RedisAdapter
|
7
|
+
* @description Adapter implementation for Redis as a memory storage solution.
|
8
|
+
* Provides integration with Redis for storing and retrieving memory entries with TTL support.
|
9
|
+
* @implements {IMemoryAdapter}
|
10
|
+
*/
|
11
|
+
export class RedisAdapter implements IMemoryAdapter {
|
12
|
+
private redis;
|
13
|
+
private readonly cachePrefix: string;
|
14
|
+
private readonly cacheTTL: number;
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Creates an instance of RedisAdapter
|
18
|
+
* @param {string} redisUrl - Redis connection URL
|
19
|
+
* @param {Object} options - Configuration options
|
20
|
+
* @param {string} [options.cachePrefix="memory:"] - Prefix for Redis keys
|
21
|
+
* @param {number} [options.cacheTTL=3600] - Default TTL in seconds
|
22
|
+
*/
|
23
|
+
constructor(
|
24
|
+
private readonly redisUrl: string,
|
25
|
+
options: {
|
26
|
+
cachePrefix?: string;
|
27
|
+
cacheTTL?: number;
|
28
|
+
}
|
29
|
+
) {
|
30
|
+
this.cachePrefix = options.cachePrefix || "memory:";
|
31
|
+
this.cacheTTL = options.cacheTTL || 3600;
|
32
|
+
this.redis = createClient({
|
33
|
+
url: redisUrl,
|
34
|
+
socket: {
|
35
|
+
tls: true,
|
36
|
+
rejectUnauthorized: true,
|
37
|
+
},
|
38
|
+
});
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Initializes the Redis connection
|
43
|
+
* @param {string} roomId - Room identifier
|
44
|
+
* @returns {Promise<void>}
|
45
|
+
*/
|
46
|
+
async init(roomId: string): Promise<void> {
|
47
|
+
this.redis.on("error", (err) => console.error("Redis Client Error:", err));
|
48
|
+
await this.redis.connect();
|
49
|
+
}
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Creates a new memory entry in Redis
|
53
|
+
* @param {CreateMemoryInput & { embedding?: number[] }} input - Memory data with optional embedding
|
54
|
+
* @returns {Promise<BaseMemoryType | undefined>} Created memory or undefined
|
55
|
+
*/
|
56
|
+
async createMemory(
|
57
|
+
input: CreateMemoryInput & { embedding?: number[] }
|
58
|
+
): Promise<BaseMemoryType | undefined> {
|
59
|
+
const memory: BaseMemoryType = {
|
60
|
+
id: input.id || crypto.randomUUID(),
|
61
|
+
data: input.data,
|
62
|
+
embedding: input.embedding,
|
63
|
+
roomId: input.roomId,
|
64
|
+
createdAt: new Date(),
|
65
|
+
};
|
66
|
+
|
67
|
+
const key = memory.roomId
|
68
|
+
? `${this.cachePrefix}${memory.roomId}:${memory.id}`
|
69
|
+
: `${this.cachePrefix}${memory.id}`;
|
70
|
+
|
71
|
+
await this.redis.set(key, JSON.stringify(memory), {
|
72
|
+
EX: this.cacheTTL,
|
73
|
+
});
|
74
|
+
|
75
|
+
return memory;
|
76
|
+
}
|
77
|
+
|
78
|
+
/**
|
79
|
+
* Retrieves a memory by ID and room ID from Redis
|
80
|
+
* @param {string} id - Memory identifier
|
81
|
+
* @param {string} roomId - Room identifier
|
82
|
+
* @returns {Promise<BaseMemoryType | null>} Memory entry or null if not found
|
83
|
+
*/
|
84
|
+
async getMemoryById(
|
85
|
+
id: string,
|
86
|
+
roomId: string
|
87
|
+
): Promise<BaseMemoryType | null> {
|
88
|
+
const key = `${this.cachePrefix}${roomId}:${id}`;
|
89
|
+
const data = await this.redis.get(key);
|
90
|
+
return data ? JSON.parse(data) : null;
|
91
|
+
}
|
92
|
+
|
93
|
+
/**
|
94
|
+
* Searches for memories in Redis based on pattern matching
|
95
|
+
* @param {string} query - Search query
|
96
|
+
* @param {Object} options - Search options
|
97
|
+
* @param {string} options.roomId - Room identifier
|
98
|
+
* @param {number} [options.limit] - Maximum number of results
|
99
|
+
* @returns {Promise<BaseMemoryType[]>} Array of matching memories
|
100
|
+
*/
|
101
|
+
async getMemoryByIndex(
|
102
|
+
query: string,
|
103
|
+
options: { roomId: string; limit?: number }
|
104
|
+
): Promise<BaseMemoryType[]> {
|
105
|
+
const pattern = `${this.cachePrefix}${options.roomId}:*`;
|
106
|
+
const keys = await this.redis.keys(pattern);
|
107
|
+
const memories = await Promise.all(
|
108
|
+
keys.map(async (key) => {
|
109
|
+
const data = await this.redis.get(key);
|
110
|
+
return data ? JSON.parse(data) : null;
|
111
|
+
})
|
112
|
+
);
|
113
|
+
return memories.filter(Boolean).slice(0, options.limit || 10);
|
114
|
+
}
|
115
|
+
|
116
|
+
/**
|
117
|
+
* Retrieves all memories for a room from Redis
|
118
|
+
* @param {string} roomId - Room identifier
|
119
|
+
* @returns {Promise<BaseMemoryType[]>} Array of all memories
|
120
|
+
*/
|
121
|
+
async getAllMemories(roomId: string): Promise<BaseMemoryType[]> {
|
122
|
+
const pattern = `${this.cachePrefix}${roomId}:*`;
|
123
|
+
const keys = await this.redis.keys(pattern);
|
124
|
+
const memories = await Promise.all(
|
125
|
+
keys.map(async (key) => {
|
126
|
+
const data = await this.redis.get(key);
|
127
|
+
return data ? JSON.parse(data) : null;
|
128
|
+
})
|
129
|
+
);
|
130
|
+
return memories.filter(Boolean);
|
131
|
+
}
|
132
|
+
|
133
|
+
/**
|
134
|
+
* Deletes a specific memory from Redis
|
135
|
+
* @param {string} id - Memory identifier
|
136
|
+
* @param {string} roomId - Room identifier
|
137
|
+
* @returns {Promise<void>}
|
138
|
+
*/
|
139
|
+
async clearMemoryById(id: string, roomId: string): Promise<void> {
|
140
|
+
const key = `${this.cachePrefix}${roomId}:${id}`;
|
141
|
+
await this.redis.del(key);
|
142
|
+
}
|
143
|
+
|
144
|
+
/**
|
145
|
+
* Clears all memories across all rooms from Redis
|
146
|
+
* @returns {Promise<void>}
|
147
|
+
*/
|
148
|
+
async clearAllMemories(): Promise<void> {
|
149
|
+
const keys = await this.redis.keys(`${this.cachePrefix}*`);
|
150
|
+
if (keys.length > 0) {
|
151
|
+
await this.redis.del(keys);
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
/**
|
156
|
+
* Closes the Redis connection
|
157
|
+
* @returns {Promise<void>}
|
158
|
+
*/
|
159
|
+
async quit(): Promise<void> {
|
160
|
+
if (this.redis) {
|
161
|
+
await this.redis.quit();
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}
|
@@ -0,0 +1,93 @@
|
|
1
|
+
import { BaseMemoryType, CreateMemoryInput } from "types";
|
2
|
+
import { BaseMemory, IMemoryAdapter } from "../../interfaces";
|
3
|
+
|
4
|
+
/**
|
5
|
+
* @module Memory
|
6
|
+
* @description A module for managing memory storage and retrieval operations.
|
7
|
+
* Implements the BaseMemory abstract class and provides concrete implementations
|
8
|
+
* for memory-related operations using the provided adapter.
|
9
|
+
* @extends {BaseMemory}
|
10
|
+
*/
|
11
|
+
export class Memory extends BaseMemory {
|
12
|
+
/**
|
13
|
+
* Creates an instance of Memory
|
14
|
+
* @param {IMemoryAdapter} adapter - The memory adapter implementation to use
|
15
|
+
*/
|
16
|
+
constructor(adapter: IMemoryAdapter) {
|
17
|
+
super(adapter);
|
18
|
+
}
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Initializes the memory module with default room
|
22
|
+
* @returns {Promise<void>}
|
23
|
+
*/
|
24
|
+
async init(): Promise<void> {
|
25
|
+
await this.adapter.init("default");
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Creates a new memory entry
|
30
|
+
* @param {CreateMemoryInput & { embedding?: number[] }} input - Memory data with optional embedding
|
31
|
+
* @returns {Promise<BaseMemoryType | undefined>} Created memory or undefined
|
32
|
+
*/
|
33
|
+
async createMemory(
|
34
|
+
input: CreateMemoryInput & { embedding?: number[] }
|
35
|
+
): Promise<BaseMemoryType | undefined> {
|
36
|
+
return this.adapter.createMemory(input);
|
37
|
+
}
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Retrieves a memory by ID and room ID
|
41
|
+
* @param {string} id - Memory identifier
|
42
|
+
* @param {string} roomId - Room identifier
|
43
|
+
* @returns {Promise<BaseMemoryType | null>} Memory entry or null if not found
|
44
|
+
*/
|
45
|
+
async getMemoryById(
|
46
|
+
id: string,
|
47
|
+
roomId: string
|
48
|
+
): Promise<BaseMemoryType | null> {
|
49
|
+
return this.adapter.getMemoryById(id, roomId);
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Searches for memories based on query and options
|
54
|
+
* @param {string} query - Search query
|
55
|
+
* @param {Object} options - Search options
|
56
|
+
* @param {string} options.roomId - Room identifier
|
57
|
+
* @param {number} [options.limit] - Maximum number of results to return
|
58
|
+
* @returns {Promise<BaseMemoryType[]>} Array of matching memories
|
59
|
+
*/
|
60
|
+
async getMemoryByIndex(
|
61
|
+
query: string,
|
62
|
+
options: { roomId: string; limit?: number }
|
63
|
+
): Promise<BaseMemoryType[]> {
|
64
|
+
return this.adapter.getMemoryByIndex(query, options);
|
65
|
+
}
|
66
|
+
|
67
|
+
/**
|
68
|
+
* Retrieves all memories for a specific room
|
69
|
+
* @param {string} roomId - Room identifier
|
70
|
+
* @returns {Promise<BaseMemoryType[]>} Array of all memories in the room
|
71
|
+
*/
|
72
|
+
async getAllMemories(roomId: string): Promise<BaseMemoryType[]> {
|
73
|
+
return this.adapter.getAllMemories(roomId);
|
74
|
+
}
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Deletes a specific memory
|
78
|
+
* @param {string} id - Memory identifier
|
79
|
+
* @param {string} roomId - Room identifier
|
80
|
+
* @returns {Promise<void>}
|
81
|
+
*/
|
82
|
+
async clearMemoryById(id: string, roomId: string): Promise<void> {
|
83
|
+
await this.adapter.clearMemoryById(id, roomId);
|
84
|
+
}
|
85
|
+
|
86
|
+
/**
|
87
|
+
* Clears all memories across all rooms
|
88
|
+
* @returns {Promise<void>}
|
89
|
+
*/
|
90
|
+
async clearAllMemories(): Promise<void> {
|
91
|
+
await this.adapter.clearAllMemories();
|
92
|
+
}
|
93
|
+
}
|
package/package.json
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ai.ntellect/core",
|
3
|
-
"version": "0.6.
|
3
|
+
"version": "0.6.19",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"scripts": {
|
7
7
|
"build": "rm -rf dist && tsc",
|
8
8
|
"test": "mocha --require ts-node/register",
|
9
|
+
"test:coverage": "nyc --reporter=text --reporter=html pnpm test",
|
9
10
|
"test:watch": "mocha --require ts-node/register 'test/**/*.test.ts' --watch"
|
10
11
|
},
|
11
12
|
"keywords": [],
|
@@ -38,6 +39,7 @@
|
|
38
39
|
"dotenv": "^16.4.7",
|
39
40
|
"meilisearch": "^0.37.0",
|
40
41
|
"mocha": "^10.0.0",
|
42
|
+
"nyc": "^17.1.0",
|
41
43
|
"redis": "^4.6.13",
|
42
44
|
"ts-node": "^10.9.0",
|
43
45
|
"typescript": "^5.7.2"
|