@ai.ntellect/core 0.6.16 → 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 +402 -0
- package/dist/index.js +22 -7
- 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 +38 -14
- package/graph/index.ts +468 -0
- package/index.ts +25 -7
- package/interfaces/index.ts +346 -28
- 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 -8
- package/modules/memory/adapters/redis/index.ts +164 -0
- package/modules/memory/index.ts +93 -0
- package/package.json +4 -4
- 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 +80 -94
- 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/tsconfig.json +0 -3
- 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/graph/graph.js +0 -162
- 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/graph/graph.ts +0 -193
- 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/.env.test +0 -4
- package/test/graph/engine.test.ts +0 -533
- package/test/memory/adapters/redis.test.ts +0 -160
- package/test/memory/base.test.ts +0 -229
- 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,8 +1,27 @@
|
|
1
|
-
import {
|
1
|
+
import { IMemoryAdapter } from "interfaces";
|
2
|
+
import { BaseMemoryType, CreateMemoryInput, MeilisearchConfig } from "types";
|
2
3
|
|
3
|
-
|
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
|
+
*/
|
4
15
|
constructor(private readonly config: MeilisearchConfig) {}
|
5
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
|
+
*/
|
6
25
|
private async makeRequest(path: string, options?: RequestInit) {
|
7
26
|
try {
|
8
27
|
const url = `${this.config.host}${path}`;
|
@@ -33,7 +52,13 @@ export class MeilisearchAdapter {
|
|
33
52
|
}
|
34
53
|
}
|
35
54
|
|
36
|
-
|
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> {
|
37
62
|
try {
|
38
63
|
let indexExists = false;
|
39
64
|
|
@@ -78,7 +103,14 @@ export class MeilisearchAdapter {
|
|
78
103
|
}
|
79
104
|
}
|
80
105
|
|
81
|
-
|
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(
|
82
114
|
documents: BaseMemoryType[],
|
83
115
|
roomId: string
|
84
116
|
): Promise<void> {
|
@@ -87,13 +119,24 @@ export class MeilisearchAdapter {
|
|
87
119
|
body: JSON.stringify(documents),
|
88
120
|
});
|
89
121
|
}
|
90
|
-
|
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> {
|
91
130
|
await this.makeRequest(`/indexes/${roomId}`, {
|
92
131
|
method: "DELETE",
|
93
132
|
});
|
94
133
|
}
|
95
134
|
|
96
|
-
|
135
|
+
/**
|
136
|
+
* Initializes the adapter for a specific room
|
137
|
+
* @param {string} roomId - Room identifier
|
138
|
+
* @returns {Promise<void>}
|
139
|
+
*/
|
97
140
|
async init(roomId: string): Promise<void> {
|
98
141
|
try {
|
99
142
|
// Initialize the default "memories" index
|
@@ -106,7 +149,17 @@ export class MeilisearchAdapter {
|
|
106
149
|
}
|
107
150
|
}
|
108
151
|
|
109
|
-
|
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(
|
110
163
|
query: string,
|
111
164
|
roomId: string,
|
112
165
|
options?: { limit?: number; threshold?: number }
|
@@ -119,6 +172,10 @@ export class MeilisearchAdapter {
|
|
119
172
|
}),
|
120
173
|
});
|
121
174
|
|
175
|
+
if (!searchResults.hits) {
|
176
|
+
return [];
|
177
|
+
}
|
178
|
+
|
122
179
|
return searchResults.hits.map((hit: any) => ({
|
123
180
|
document: {
|
124
181
|
id: hit.id,
|
@@ -131,17 +188,30 @@ export class MeilisearchAdapter {
|
|
131
188
|
}));
|
132
189
|
}
|
133
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
|
+
*/
|
134
196
|
async createMemory(
|
135
197
|
input: CreateMemoryInput & { embedding?: number[] }
|
136
198
|
): Promise<BaseMemoryType | undefined> {
|
137
199
|
// Initialize storage for this roomId if needed
|
138
200
|
await this.initializeStorage(input.roomId);
|
139
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
|
+
|
140
210
|
// If not found, create new memory
|
141
211
|
const memory: BaseMemoryType = {
|
142
212
|
id: input.id || crypto.randomUUID(),
|
143
213
|
data: input.data,
|
144
|
-
embedding: input.embedding
|
214
|
+
embedding: input.embedding,
|
145
215
|
roomId: input.roomId,
|
146
216
|
createdAt: new Date(),
|
147
217
|
};
|
@@ -150,6 +220,12 @@ export class MeilisearchAdapter {
|
|
150
220
|
return memory;
|
151
221
|
}
|
152
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
|
+
*/
|
153
229
|
async getMemoryById(
|
154
230
|
id: string,
|
155
231
|
roomId: string
|
@@ -172,6 +248,14 @@ export class MeilisearchAdapter {
|
|
172
248
|
}
|
173
249
|
}
|
174
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
|
+
*/
|
175
259
|
async getMemoryByIndex(
|
176
260
|
query: string,
|
177
261
|
options: { roomId: string; limit?: number }
|
@@ -190,6 +274,11 @@ export class MeilisearchAdapter {
|
|
190
274
|
}));
|
191
275
|
}
|
192
276
|
|
277
|
+
/**
|
278
|
+
* Retrieves all memories for a room
|
279
|
+
* @param {string} roomId - Room identifier
|
280
|
+
* @returns {Promise<BaseMemoryType[]>} Array of all memories
|
281
|
+
*/
|
193
282
|
async getAllMemories(roomId: string): Promise<BaseMemoryType[]> {
|
194
283
|
const results = await this.makeRequest(`/indexes/${roomId}/documents`);
|
195
284
|
if (results.total === 0) {
|
@@ -205,6 +294,12 @@ export class MeilisearchAdapter {
|
|
205
294
|
}));
|
206
295
|
}
|
207
296
|
|
297
|
+
/**
|
298
|
+
* Deletes a specific memory
|
299
|
+
* @param {string} id - Memory identifier
|
300
|
+
* @param {string} roomId - Room identifier
|
301
|
+
* @returns {Promise<void>}
|
302
|
+
*/
|
208
303
|
async clearMemoryById(id: string, roomId: string): Promise<void> {
|
209
304
|
try {
|
210
305
|
// Ensure the index exists before attempting to delete
|
@@ -226,6 +321,10 @@ export class MeilisearchAdapter {
|
|
226
321
|
}
|
227
322
|
}
|
228
323
|
|
324
|
+
/**
|
325
|
+
* Clears all memories across all rooms
|
326
|
+
* @returns {Promise<void>}
|
327
|
+
*/
|
229
328
|
async clearAllMemories(): Promise<void> {
|
230
329
|
try {
|
231
330
|
// Get all indexes
|
@@ -244,8 +343,15 @@ export class MeilisearchAdapter {
|
|
244
343
|
}
|
245
344
|
}
|
246
345
|
|
346
|
+
/**
|
347
|
+
* @interface SearchResult
|
348
|
+
* @description Interface for search results from Meilisearch
|
349
|
+
*/
|
247
350
|
interface SearchResult {
|
351
|
+
/** The matched document */
|
248
352
|
document?: any;
|
353
|
+
/** Relevance score of the match */
|
249
354
|
score?: number;
|
355
|
+
/** Array of additional results */
|
250
356
|
results?: any[];
|
251
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
|
-
"build": "rm -rf dist && tsc
|
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,10 +39,9 @@
|
|
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
|
-
"tsc-alias": "^1.8.10",
|
44
|
-
"tsconfig-paths": "^4.2.0",
|
45
45
|
"typescript": "^5.7.2"
|
46
46
|
},
|
47
47
|
"repository": {
|