@ai.ntellect/core 0.4.1 → 0.6.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.
Files changed (125) hide show
  1. package/.mocharc.json +1 -1
  2. package/README.md +311 -272
  3. package/dist/graph/controller.js +63 -0
  4. package/dist/graph/engine.js +563 -0
  5. package/dist/index.js +6 -6
  6. package/dist/memory/adapters/meilisearch/index.js +249 -0
  7. package/dist/memory/adapters/redis/index.js +96 -0
  8. package/dist/memory/index.js +9 -0
  9. package/dist/services/agenda.js +115 -0
  10. package/dist/services/embedding.js +40 -0
  11. package/dist/services/queue.js +99 -103
  12. package/dist/test/graph/controller.test.js +170 -0
  13. package/dist/test/graph/engine.test.js +465 -0
  14. package/dist/test/memory/adapters/meilisearch.test.js +250 -0
  15. package/dist/test/memory/adapters/redis.test.js +143 -0
  16. package/dist/test/memory/base.test.js +209 -0
  17. package/dist/test/services/agenda.test.js +230 -0
  18. package/dist/test/services/queue.test.js +258 -0
  19. package/dist/types/index.js +2 -0
  20. package/dist/utils/generate-object.js +32 -11
  21. package/dist/utils/inject-actions.js +2 -2
  22. package/dist/utils/queue-item-transformer.js +2 -2
  23. package/dist/utils/state-manager.js +20 -0
  24. package/graph/controller.ts +60 -0
  25. package/graph/engine.ts +709 -0
  26. package/index.ts +7 -7
  27. package/interfaces/index.ts +119 -0
  28. package/memory/adapters/meilisearch/index.ts +286 -0
  29. package/memory/adapters/redis/index.ts +103 -0
  30. package/memory/index.ts +22 -0
  31. package/package.json +9 -2
  32. package/services/agenda.ts +118 -0
  33. package/services/embedding.ts +26 -0
  34. package/services/queue.ts +5 -32
  35. package/test/.env.test +4 -0
  36. package/test/graph/controller.test.ts +186 -0
  37. package/test/graph/engine.test.ts +563 -0
  38. package/test/memory/adapters/meilisearch.test.ts +297 -0
  39. package/test/memory/adapters/redis.test.ts +160 -0
  40. package/test/memory/base.test.ts +229 -0
  41. package/test/services/agenda.test.ts +280 -0
  42. package/test/services/queue.test.ts +286 -44
  43. package/tsconfig.json +10 -9
  44. package/types/index.ts +270 -0
  45. package/utils/generate-object.js +111 -0
  46. package/utils/generate-object.ts +24 -12
  47. package/utils/header-builder.js +34 -0
  48. package/utils/inject-actions.js +16 -0
  49. package/utils/inject-actions.ts +3 -3
  50. package/utils/queue-item-transformer.js +24 -0
  51. package/utils/queue-item-transformer.ts +8 -11
  52. package/utils/sanitize-results.js +60 -0
  53. package/utils/schema-generator.js +46 -0
  54. package/utils/state-manager.js +20 -0
  55. package/utils/state-manager.ts +30 -0
  56. package/.nvmrc +0 -1
  57. package/README.FR.md +0 -365
  58. package/agent/index.ts +0 -244
  59. package/agent/tools/get-rss.ts +0 -64
  60. package/bull.ts +0 -5
  61. package/dist/agent/index.d.ts +0 -38
  62. package/dist/agent/index.js +0 -143
  63. package/dist/agent/tools/get-rss.d.ts +0 -16
  64. package/dist/agent/tools/get-rss.js +0 -62
  65. package/dist/bull.d.ts +0 -1
  66. package/dist/bull.js +0 -9
  67. package/dist/examples/index.d.ts +0 -2
  68. package/dist/examples/index.js +0 -89
  69. package/dist/index.d.ts +0 -7
  70. package/dist/llm/interpreter/context.d.ts +0 -15
  71. package/dist/llm/interpreter/context.js +0 -89
  72. package/dist/llm/interpreter/index.d.ts +0 -21
  73. package/dist/llm/interpreter/index.js +0 -87
  74. package/dist/llm/memory-manager/context.d.ts +0 -2
  75. package/dist/llm/memory-manager/context.js +0 -22
  76. package/dist/llm/memory-manager/index.d.ts +0 -17
  77. package/dist/llm/memory-manager/index.js +0 -107
  78. package/dist/llm/orchestrator/context.d.ts +0 -2
  79. package/dist/llm/orchestrator/context.js +0 -23
  80. package/dist/llm/orchestrator/index.d.ts +0 -44
  81. package/dist/llm/orchestrator/index.js +0 -139
  82. package/dist/llm/orchestrator/types.d.ts +0 -12
  83. package/dist/memory/cache.d.ts +0 -22
  84. package/dist/memory/cache.js +0 -165
  85. package/dist/memory/persistent.d.ts +0 -57
  86. package/dist/memory/persistent.js +0 -189
  87. package/dist/services/queue.d.ts +0 -13
  88. package/dist/services/redis-cache.d.ts +0 -37
  89. package/dist/services/redis-cache.js +0 -93
  90. package/dist/services/scheduler.d.ts +0 -40
  91. package/dist/services/scheduler.js +0 -99
  92. package/dist/services/telegram-monitor.d.ts +0 -0
  93. package/dist/services/telegram-monitor.js +0 -118
  94. package/dist/t.d.ts +0 -46
  95. package/dist/t.js +0 -102
  96. package/dist/test.d.ts +0 -0
  97. package/dist/test.js +0 -438
  98. package/dist/types.d.ts +0 -258
  99. package/dist/types.js +0 -22
  100. package/dist/utils/generate-object.d.ts +0 -12
  101. package/dist/utils/header-builder.d.ts +0 -11
  102. package/dist/utils/inject-actions.d.ts +0 -2
  103. package/dist/utils/queue-item-transformer.d.ts +0 -7
  104. package/dist/utils/sanitize-results.d.ts +0 -17
  105. package/dist/utils/schema-generator.d.ts +0 -16
  106. package/examples/index.ts +0 -103
  107. package/llm/interpreter/context.ts +0 -101
  108. package/llm/interpreter/index.ts +0 -136
  109. package/llm/memory-manager/context.ts +0 -21
  110. package/llm/memory-manager/index.ts +0 -163
  111. package/llm/orchestrator/context.ts +0 -22
  112. package/llm/orchestrator/index.ts +0 -232
  113. package/llm/orchestrator/types.ts +0 -14
  114. package/memory/cache.ts +0 -221
  115. package/memory/persistent.ts +0 -265
  116. package/services/redis-cache.ts +0 -128
  117. package/services/scheduler.ts +0 -128
  118. package/services/telegram-monitor.ts +0 -138
  119. package/t.py +0 -79
  120. package/t.spec +0 -38
  121. package/t.ts +0 -133
  122. package/test/llm/orchestrator.test.ts +0 -47
  123. package/test/llm/synthesizer.test.ts +0 -31
  124. package/types.ts +0 -288
  125. /package/dist/{llm/orchestrator/types.js → interfaces/index.js} +0 -0
package/index.ts CHANGED
@@ -1,8 +1,8 @@
1
- export * from "./agent";
2
- export * from "./llm/interpreter";
3
- export * from "./llm/interpreter/context";
4
- export * from "./llm/orchestrator";
5
- export * from "./types";
1
+ export * from "./graph/controller";
2
+ export * from "./graph/engine";
3
+ export * from "./memory";
4
+ export * from "./memory/adapters/meilisearch";
5
+ export * from "./memory/adapters/redis";
6
6
 
7
- export * from "./memory/cache";
8
- export * from "./memory/persistent";
7
+ export * from "./interfaces";
8
+ export * from "./types";
@@ -0,0 +1,119 @@
1
+ import { BaseMemoryType } from "@/types";
2
+ import { SharedState } from "@/types";
3
+
4
+ /* ======================== PERSISTENCE ======================== */
5
+
6
+ /**
7
+ * Interface for persisting graph execution state.
8
+ */
9
+ export interface Persistence<T> {
10
+ saveState(
11
+ graphName: string,
12
+ state: SharedState<T>,
13
+ currentNode: string
14
+ ): Promise<void>;
15
+ loadState(
16
+ graphName: string
17
+ ): Promise<{ state: SharedState<T>; currentNode: string } | null>;
18
+ }
19
+
20
+ /* ======================== REAL-TIME NOTIFICATIONS ======================== */
21
+
22
+ /**
23
+ * Interface for real-time notifications.
24
+ */
25
+ export interface RealTimeNotifier {
26
+ notify(event: string, data: any): void;
27
+ }
28
+
29
+ /* ======================== EMBEDDING SERVICE ======================== */
30
+
31
+ /**
32
+ * Interface for an embedding service that processes text into vector representations.
33
+ */
34
+ export interface EmbeddingService {
35
+ /**
36
+ * Generates an embedding for a single text.
37
+ * @param {string} text - The input text to embed.
38
+ * @returns {Promise<number[]>} - A vector representation of the text.
39
+ */
40
+ embedText(text: string): Promise<number[]>;
41
+
42
+ /**
43
+ * Generates embeddings for multiple texts at once.
44
+ * @param {string[]} texts - The array of texts to embed.
45
+ * @returns {Promise<number[][]>} - A list of vector representations.
46
+ */
47
+ embedMany(texts: string[]): Promise<number[][]>;
48
+
49
+ /**
50
+ * Calculates the similarity between two embeddings.
51
+ * @param {number[]} embedding1 - First vector.
52
+ * @param {number[]} embedding2 - Second vector.
53
+ * @returns {number} - A similarity score between the two vectors.
54
+ */
55
+ calculateSimilarity(embedding1: number[], embedding2: number[]): number;
56
+ }
57
+
58
+ /* ======================== MEMORY SERVICE ======================== */
59
+
60
+ /**
61
+ * Interface for managing memory storage and retrieval.
62
+ */
63
+ export interface BaseMemoryService {
64
+ /**
65
+ * Initializes the memory storage connection.
66
+ * @returns {Promise<void>} - Resolves when initialization is complete.
67
+ */
68
+ initializeConnection(): Promise<void>;
69
+
70
+ /**
71
+ * Stores a new memory entry.
72
+ * @param {BaseMemoryType} memory - The memory data to store.
73
+ * @param {number} [ttl] - Optional time-to-live in seconds.
74
+ * @returns {Promise<void>}
75
+ */
76
+ createMemory(memory: BaseMemoryType, ttl?: number): Promise<void>;
77
+
78
+ /**
79
+ * Retrieves a memory entry by its unique ID.
80
+ * @param {string} id - The memory entry identifier.
81
+ * @returns {Promise<BaseMemoryType | null>} - The found memory or null.
82
+ */
83
+ getMemoryById(id: string): Promise<BaseMemoryType | null>;
84
+
85
+ /**
86
+ * Searches for memory entries based on a query and optional constraints.
87
+ * @param {string} query - The search query.
88
+ * @param {Object} options - Search options.
89
+ * @param {string} options.roomId - The room identifier.
90
+ * @param {number} [options.limit] - Maximum number of results (optional).
91
+ * @returns {Promise<BaseMemoryType[]>} - A list of matched memory entries.
92
+ */
93
+ getMemoryByIndex(
94
+ query: string,
95
+ options: {
96
+ roomId: string;
97
+ limit?: number;
98
+ }
99
+ ): Promise<BaseMemoryType[]>;
100
+
101
+ /**
102
+ * Retrieves all stored memory entries.
103
+ * @returns {Promise<BaseMemoryType[]>} - A list of all memory entries.
104
+ */
105
+ getAllMemories(): Promise<BaseMemoryType[]>;
106
+
107
+ /**
108
+ * Deletes a memory entry by its unique ID.
109
+ * @param {string} id - The memory entry identifier.
110
+ * @returns {Promise<void>}
111
+ */
112
+ clearMemoryById(id: string): Promise<void>;
113
+
114
+ /**
115
+ * Clears all stored memory entries.
116
+ * @returns {Promise<void>}
117
+ */
118
+ clearAllMemories(): Promise<void>;
119
+ }
@@ -0,0 +1,286 @@
1
+ import { BaseMemoryService } from "@/interfaces";
2
+ import { BaseMemory } from "@/memory";
3
+ import { BaseMemoryType, CreateMemoryInput, MeilisearchConfig } from "@/types";
4
+
5
+ export class MeilisearchAdapter extends BaseMemory {
6
+ constructor(
7
+ private readonly config: MeilisearchConfig,
8
+ baseMemoryService: BaseMemoryService
9
+ ) {
10
+ super(baseMemoryService);
11
+ }
12
+
13
+ private async makeRequest(path: string, options?: RequestInit) {
14
+ try {
15
+ const url = `${this.config.host}${path}`;
16
+ const response = await fetch(url, {
17
+ ...options,
18
+ headers: {
19
+ "Content-Type": "application/json",
20
+ Authorization: `Bearer ${this.config.apiKey}`,
21
+ ...options?.headers,
22
+ },
23
+ });
24
+
25
+ if (!response.ok) {
26
+ const errorBody = await response.text();
27
+ throw new Error(
28
+ `HTTP ${response.status}: ${errorBody || response.statusText}`
29
+ );
30
+ }
31
+
32
+ return response.json();
33
+ } catch (error) {
34
+ if (error instanceof TypeError && error.message === "Failed to fetch") {
35
+ throw new Error(
36
+ `Network error: Unable to connect to Meilisearch at ${this.config.host}`
37
+ );
38
+ }
39
+ throw error;
40
+ }
41
+ }
42
+
43
+ async initializeStorage(roomId: string): Promise<void> {
44
+ try {
45
+ let indexExists = false;
46
+
47
+ try {
48
+ // Check if index exists
49
+ await this.makeRequest(`/indexes/${roomId}`);
50
+ indexExists = true;
51
+ } catch (error) {
52
+ // Only continue if the error is "Not found"
53
+ if (!(error instanceof Error && error.message.includes("Not found"))) {
54
+ throw error;
55
+ }
56
+ }
57
+
58
+ if (!indexExists) {
59
+ // Create new index
60
+ await this.makeRequest("/indexes", {
61
+ method: "POST",
62
+ body: JSON.stringify({
63
+ uid: roomId,
64
+ primaryKey: "id",
65
+ }),
66
+ });
67
+
68
+ // Wait for index creation
69
+ await new Promise((resolve) => setTimeout(resolve, 1000));
70
+ }
71
+
72
+ // Update settings
73
+ await this.makeRequest(`/indexes/${roomId}/settings`, {
74
+ method: "PATCH",
75
+ body: JSON.stringify({
76
+ searchableAttributes: this.config.searchableAttributes || [
77
+ "data",
78
+ "query",
79
+ ],
80
+ sortableAttributes: this.config.sortableAttributes || ["createdAt"],
81
+ }),
82
+ });
83
+ } catch (error) {
84
+ const errorMessage =
85
+ error instanceof Error ? error.message : "Unknown error";
86
+ console.error(
87
+ `Error initializing storage for index ${roomId}:`,
88
+ errorMessage
89
+ );
90
+ throw new Error(
91
+ `Failed to initialize storage for index ${roomId}: ${errorMessage}`
92
+ );
93
+ }
94
+ }
95
+
96
+ async addDocuments(
97
+ documents: BaseMemoryType[],
98
+ roomId: string
99
+ ): Promise<void> {
100
+ await this.makeRequest(`/indexes/${roomId}/documents`, {
101
+ method: "POST",
102
+ body: JSON.stringify(documents),
103
+ });
104
+ }
105
+
106
+ async search(
107
+ query: string,
108
+ roomId: string,
109
+ options?: { limit?: number; threshold?: number }
110
+ ): Promise<SearchResult[]> {
111
+ const searchResults = await this.makeRequest(`/indexes/${roomId}/search`, {
112
+ method: "POST",
113
+ body: JSON.stringify({
114
+ q: query,
115
+ limit: options?.limit || 10,
116
+ }),
117
+ });
118
+
119
+ return searchResults.hits.map((hit: any) => ({
120
+ document: {
121
+ id: hit.id,
122
+ data: hit.data,
123
+ query: hit.query,
124
+ embedding: hit.embedding,
125
+ roomId: hit.roomId,
126
+ createdAt: hit.createdAt,
127
+ },
128
+ score: hit._score || 0,
129
+ }));
130
+ }
131
+
132
+ async deleteStorage(roomId: string): Promise<void> {
133
+ await this.makeRequest(`/indexes/${roomId}`, {
134
+ method: "DELETE",
135
+ });
136
+ }
137
+
138
+ // Required BaseMemory implementations
139
+ async init(): Promise<void> {
140
+ try {
141
+ // Initialize the default "memories" index
142
+ await this.initializeStorage("memories");
143
+ } catch (error) {
144
+ const errorMessage =
145
+ error instanceof Error ? error.message : "Unknown error";
146
+ console.error("Failed to initialize default index:", errorMessage);
147
+ throw new Error(`Failed to initialize default index: ${errorMessage}`);
148
+ }
149
+ }
150
+
151
+ async createMemory(
152
+ input: CreateMemoryInput & { embedding?: number[] }
153
+ ): Promise<BaseMemoryType | undefined> {
154
+ // Initialize storage for this roomId if needed
155
+ await this.initializeStorage(input.roomId);
156
+
157
+ // Search for existing memory with same data and query
158
+ const searchResults = await this.search(input.data, input.roomId, {
159
+ limit: 1,
160
+ });
161
+ const existingMemory = searchResults.find(
162
+ (result) =>
163
+ result.document.data === input.data &&
164
+ result.document.query === input.query &&
165
+ result.document.roomId === input.roomId
166
+ );
167
+
168
+ // If found, return existing memory
169
+ if (existingMemory) {
170
+ return existingMemory.document;
171
+ }
172
+
173
+ // If not found, create new memory
174
+ const memory: BaseMemoryType = {
175
+ id: crypto.randomUUID(),
176
+ data: input.data,
177
+ query: input.query,
178
+ embedding: input.embedding || null,
179
+ roomId: input.roomId,
180
+ createdAt: new Date(),
181
+ };
182
+
183
+ await this.addDocuments([memory], input.roomId);
184
+ return memory;
185
+ }
186
+
187
+ async getMemoryById(
188
+ id: string,
189
+ roomId: string
190
+ ): Promise<BaseMemoryType | null> {
191
+ try {
192
+ const result = await this.makeRequest(
193
+ `/indexes/${roomId}/documents/${id}`
194
+ );
195
+ return result
196
+ ? {
197
+ id: result.id,
198
+ data: result.data,
199
+ query: result.query,
200
+ embedding: result.embedding,
201
+ roomId: result.roomId,
202
+ createdAt: result.createdAt,
203
+ }
204
+ : null;
205
+ } catch {
206
+ return null;
207
+ }
208
+ }
209
+
210
+ async getMemoryByIndex(
211
+ query: string,
212
+ options: { roomId: string; limit?: number }
213
+ ): Promise<BaseMemoryType[]> {
214
+ const results = await this.search(query, options.roomId, {
215
+ limit: options.limit,
216
+ });
217
+ return results
218
+ .filter((result) => result.document.roomId === options.roomId)
219
+ .map((result) => ({
220
+ id: result.document.id,
221
+ data: result.document.data,
222
+ query: result.document.query,
223
+ embedding: result.document.embedding,
224
+ roomId: result.document.roomId,
225
+ createdAt: result.document.createdAt,
226
+ }));
227
+ }
228
+
229
+ async getAllMemories(roomId: string): Promise<BaseMemoryType[]> {
230
+ const results = await this.makeRequest(`/indexes/${roomId}/documents`);
231
+ return results.map((doc: any) => ({
232
+ id: doc.id,
233
+ data: doc.data,
234
+ query: doc.query,
235
+ embedding: doc.embedding,
236
+ roomId: doc.roomId,
237
+ createdAt: doc.createdAt,
238
+ }));
239
+ }
240
+
241
+ async clearMemoryById(id: string, roomId: string): Promise<void> {
242
+ try {
243
+ // Ensure the index exists before attempting to delete
244
+ await this.initializeStorage(roomId);
245
+
246
+ await this.makeRequest(`/indexes/${roomId}/documents/${id}`, {
247
+ method: "DELETE",
248
+ });
249
+ } catch (error) {
250
+ const errorMessage =
251
+ error instanceof Error ? error.message : "Unknown error";
252
+ console.error(
253
+ `Error clearing memory ${id} from index ${roomId}:`,
254
+ errorMessage
255
+ );
256
+ throw new Error(
257
+ `Failed to clear memory ${id} from index ${roomId}: ${errorMessage}`
258
+ );
259
+ }
260
+ }
261
+
262
+ async clearAllMemories(): Promise<void> {
263
+ try {
264
+ // Get all indexes
265
+ const response = await this.makeRequest("/indexes");
266
+ const indexes = response.results || [];
267
+
268
+ // Delete each index
269
+ for (const index of indexes) {
270
+ await this.deleteStorage(index.uid);
271
+ }
272
+
273
+ // Reinitialize the default index
274
+ await this.init();
275
+ } catch (error) {
276
+ const errorMessage =
277
+ error instanceof Error ? error.message : "Unknown error";
278
+ throw new Error(`Failed to clear all memories: ${errorMessage}`);
279
+ }
280
+ }
281
+ }
282
+
283
+ interface SearchResult {
284
+ document: BaseMemoryType;
285
+ score: number;
286
+ }
@@ -0,0 +1,103 @@
1
+ import { BaseMemoryService } from "@/interfaces";
2
+ import { BaseMemoryType } from "@/types";
3
+ import { createClient } from "redis";
4
+
5
+ export class RedisAdapter implements BaseMemoryService {
6
+ private redis;
7
+ private readonly cachePrefix: string;
8
+ private readonly cacheTTL: number;
9
+
10
+ constructor(
11
+ private readonly redisUrl: string,
12
+ options: {
13
+ cachePrefix?: string;
14
+ cacheTTL?: number;
15
+ }
16
+ ) {
17
+ this.cachePrefix = options.cachePrefix || "memory:";
18
+ this.cacheTTL = options.cacheTTL || 3600;
19
+ this.redis = createClient({
20
+ url: redisUrl,
21
+ socket: {
22
+ tls: true,
23
+ rejectUnauthorized: true,
24
+ },
25
+ });
26
+ }
27
+
28
+ async initializeConnection(): Promise<void> {
29
+ this.redis.on("error", (err) => console.error("Redis Client Error:", err));
30
+ await this.redis.connect();
31
+ }
32
+
33
+ async createMemory(memory: BaseMemoryType, ttl?: number): Promise<void> {
34
+ const key = memory.roomId
35
+ ? `${this.cachePrefix}${memory.roomId}:${memory.id}`
36
+ : `${this.cachePrefix}${memory.id}`;
37
+
38
+ await this.redis.set(key, JSON.stringify(memory), {
39
+ EX: ttl || this.cacheTTL,
40
+ });
41
+ }
42
+
43
+ async getMemoryById(
44
+ id: string,
45
+ roomId?: string
46
+ ): Promise<BaseMemoryType | null> {
47
+ const key = roomId
48
+ ? `${this.cachePrefix}${roomId}:${id}`
49
+ : `${this.cachePrefix}${id}`;
50
+
51
+ const data = await this.redis.get(key);
52
+ return data ? JSON.parse(data) : null;
53
+ }
54
+
55
+ async getMemoryByIndex(
56
+ query: string,
57
+ options: {
58
+ roomId?: string;
59
+ limit?: number;
60
+ } = {}
61
+ ): Promise<BaseMemoryType[]> {
62
+ const pattern = options.roomId
63
+ ? `${this.cachePrefix}${options.roomId}:*`
64
+ : `${this.cachePrefix}*`;
65
+
66
+ const keys = await this.redis.keys(pattern);
67
+ const memories = await Promise.all(
68
+ keys.map(async (key) => {
69
+ const data = await this.redis.get(key);
70
+ return data ? JSON.parse(data) : null;
71
+ })
72
+ );
73
+ return memories.filter(Boolean).slice(0, options.limit || 10);
74
+ }
75
+
76
+ async getAllMemories(): Promise<BaseMemoryType[]> {
77
+ const keys = await this.redis.keys(`${this.cachePrefix}*`);
78
+ const memories = await Promise.all(
79
+ keys.map(async (key) => {
80
+ const data = await this.redis.get(key);
81
+ return data ? JSON.parse(data) : null;
82
+ })
83
+ );
84
+ return memories.filter(Boolean);
85
+ }
86
+
87
+ async clearMemoryById(id: string): Promise<void> {
88
+ await this.redis.del(`${this.cachePrefix}${id}`);
89
+ }
90
+
91
+ async clearAllMemories(): Promise<void> {
92
+ const keys = await this.redis.keys(`${this.cachePrefix}*`);
93
+ if (keys.length > 0) {
94
+ await this.redis.del(keys);
95
+ }
96
+ }
97
+
98
+ async quit(): Promise<void> {
99
+ if (this.redis) {
100
+ await this.redis.quit();
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,22 @@
1
+ import { BaseMemoryService } from "@/interfaces";
2
+ import { BaseMemoryType, CreateMemoryInput } from "@/types";
3
+
4
+ export abstract class BaseMemory {
5
+ constructor(protected readonly cacheService: BaseMemoryService) {}
6
+
7
+ abstract init(): Promise<void>;
8
+ abstract createMemory(
9
+ input: CreateMemoryInput & { embedding?: number[] }
10
+ ): Promise<BaseMemoryType | undefined>;
11
+ abstract getMemoryById(
12
+ id: string,
13
+ roomId: string
14
+ ): Promise<BaseMemoryType | null>;
15
+ abstract getMemoryByIndex(
16
+ query: string,
17
+ options: { roomId: string; limit?: number }
18
+ ): Promise<BaseMemoryType[]>;
19
+ abstract getAllMemories(roomId: string): Promise<BaseMemoryType[]>;
20
+ abstract clearMemoryById(id: string, roomId: string): Promise<void>;
21
+ abstract clearAllMemories(): Promise<void>;
22
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai.ntellect/core",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -16,12 +16,15 @@
16
16
  "@ai-sdk/openai": "1.0.6",
17
17
  "@types/node-cron": "^3.0.11",
18
18
  "ai": "^3.0.0",
19
+ "chalk": "^5.4.1",
19
20
  "ethers": "^6.13.5",
21
+ "ioredis": "^5.4.2",
20
22
  "langchain": "^0.3.11",
21
23
  "node-cron": "^3.0.3",
22
24
  "readline": "^1.3.0",
23
25
  "redis": "^4.7.0",
24
26
  "rss-parser": "^3.13.0",
27
+ "sinon": "^19.0.2",
25
28
  "ws": "^8.18.0",
26
29
  "zod": "^3.24.1"
27
30
  },
@@ -29,12 +32,16 @@
29
32
  "@jest/globals": "^29.7.0",
30
33
  "@types/chai": "^4.3.20",
31
34
  "@types/mocha": "^10.0.0",
35
+ "@types/sinon": "^17.0.3",
32
36
  "@types/ws": "^8.5.14",
33
37
  "chai": "^4.5.0",
34
38
  "mocha": "^10.0.0",
35
39
  "ts-node": "^10.9.0",
36
40
  "tsconfig-paths": "^4.2.0",
37
- "typescript": "^5.7.2"
41
+ "typescript": "^5.7.2",
42
+ "meilisearch": "^0.37.0",
43
+ "redis": "^4.6.13",
44
+ "dotenv": "^16.4.5"
38
45
  },
39
46
  "repository": {
40
47
  "type": "git",
@@ -0,0 +1,118 @@
1
+ import { ScheduledRequest } from "@/types";
2
+ import cron from "node-cron";
3
+
4
+ export class Agenda {
5
+ private scheduledRequests: Map<string, ScheduledRequest> = new Map();
6
+ private cronJobs: Map<string, cron.ScheduledTask> = new Map();
7
+
8
+ /**
9
+ * Schedule a new request to be processed later
10
+ */
11
+ async scheduleRequest(
12
+ request: {
13
+ originalRequest: string;
14
+ cronExpression: string;
15
+ },
16
+ callbacks?: {
17
+ onScheduled?: (id: string) => void;
18
+ onExecuted?: (id: string, originalRequest: string) => void;
19
+ }
20
+ ): Promise<string> {
21
+ const id = crypto.randomUUID();
22
+
23
+ const scheduledRequest: ScheduledRequest = {
24
+ id,
25
+ originalRequest: request.originalRequest,
26
+ cronExpression: request.cronExpression,
27
+ isRecurring: false,
28
+ createdAt: new Date(),
29
+ };
30
+
31
+ // Create cron job
32
+ const cronJob = cron.schedule(request.cronExpression, () => {
33
+ console.log(`🔄 Executing scheduled request: ${id}`);
34
+
35
+ if (callbacks?.onExecuted) {
36
+ callbacks.onExecuted(id, scheduledRequest.originalRequest);
37
+ }
38
+
39
+ console.log(`✅ Scheduled request executed successfully: ${id}`);
40
+
41
+ // Auto-stop pour les tâches non récurrentes
42
+ if (!scheduledRequest.isRecurring) {
43
+ this.cancelScheduledRequest(id);
44
+ }
45
+ });
46
+
47
+ // Démarrer le job en mode non-running
48
+ cronJob.stop();
49
+
50
+ // Store request and job
51
+ this.scheduledRequests.set(id, scheduledRequest);
52
+ this.cronJobs.set(id, cronJob);
53
+
54
+ if (callbacks?.onScheduled) callbacks.onScheduled(id);
55
+
56
+ // Démarrer le job après l'avoir stocké
57
+ cronJob.start();
58
+
59
+ return id;
60
+ }
61
+
62
+ /**
63
+ * Cancel a scheduled request
64
+ */
65
+ cancelScheduledRequest(requestId: string): boolean {
66
+ const cronJob = this.cronJobs.get(requestId);
67
+ if (cronJob) {
68
+ try {
69
+ cronJob.stop();
70
+ this.cronJobs.delete(requestId);
71
+ this.scheduledRequests.delete(requestId);
72
+ return true;
73
+ } catch (error) {
74
+ console.error(`Failed to stop cron job ${requestId}:`, error);
75
+ return false;
76
+ }
77
+ }
78
+ return false;
79
+ }
80
+
81
+ /**
82
+ * Get all scheduled requests
83
+ */
84
+ getScheduledRequests(): ScheduledRequest[] {
85
+ return Array.from(this.scheduledRequests.values());
86
+ }
87
+
88
+ /**
89
+ * Stop all cron jobs
90
+ */
91
+ stopAll(): void {
92
+ const ids = Array.from(this.cronJobs.keys());
93
+
94
+ // Arrêter tous les jobs de manière synchrone
95
+ for (const id of ids) {
96
+ const job = this.cronJobs.get(id);
97
+ if (job) {
98
+ job.stop();
99
+ this.cronJobs.delete(id);
100
+ this.scheduledRequests.delete(id);
101
+ }
102
+ }
103
+
104
+ // Double vérification
105
+ this.cronJobs.clear();
106
+ this.scheduledRequests.clear();
107
+ }
108
+
109
+ public async stop(): Promise<void> {
110
+ this.stopAll();
111
+ await new Promise((resolve) => setTimeout(resolve, 100));
112
+ }
113
+
114
+ public async cancel(query: {}): Promise<void> {
115
+ this.stopAll();
116
+ await new Promise((resolve) => setTimeout(resolve, 100));
117
+ }
118
+ }