@ai.ntellect/core 0.5.0 → 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 (131) 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/{services/workflow.ts → graph/engine.ts} +331 -113
  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 +7 -2
  32. package/services/agenda.ts +48 -43
  33. package/services/embedding.ts +26 -0
  34. package/services/queue.ts +2 -29
  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 -10
  44. package/types/index.ts +270 -0
  45. package/utils/generate-object.js +111 -0
  46. package/utils/header-builder.js +34 -0
  47. package/utils/inject-actions.js +16 -0
  48. package/utils/queue-item-transformer.js +24 -0
  49. package/utils/queue-item-transformer.ts +8 -11
  50. package/utils/sanitize-results.js +60 -0
  51. package/utils/schema-generator.js +46 -0
  52. package/utils/state-manager.js +20 -0
  53. package/utils/state-manager.ts +17 -12
  54. package/.nvmrc +0 -1
  55. package/README.FR.md +0 -916
  56. package/agent/index.ts +0 -151
  57. package/agent/workflow/conditions.ts +0 -16
  58. package/agent/workflow/handlers/interpreter.handler.ts +0 -48
  59. package/agent/workflow/handlers/memory.handler.ts +0 -106
  60. package/agent/workflow/handlers/orchestrator.handler.ts +0 -23
  61. package/agent/workflow/handlers/queue.handler.ts +0 -34
  62. package/agent/workflow/handlers/scheduler.handler.ts +0 -61
  63. package/agent/workflow/index.ts +0 -62
  64. package/dist/agent/index.d.ts +0 -38
  65. package/dist/agent/index.js +0 -143
  66. package/dist/agent/tools/get-rss.d.ts +0 -16
  67. package/dist/agent/tools/get-rss.js +0 -62
  68. package/dist/bull.d.ts +0 -1
  69. package/dist/bull.js +0 -9
  70. package/dist/examples/index.d.ts +0 -2
  71. package/dist/examples/index.js +0 -89
  72. package/dist/index.d.ts +0 -7
  73. package/dist/llm/interpreter/context.d.ts +0 -15
  74. package/dist/llm/interpreter/context.js +0 -89
  75. package/dist/llm/interpreter/index.d.ts +0 -21
  76. package/dist/llm/interpreter/index.js +0 -87
  77. package/dist/llm/memory-manager/context.d.ts +0 -2
  78. package/dist/llm/memory-manager/context.js +0 -22
  79. package/dist/llm/memory-manager/index.d.ts +0 -17
  80. package/dist/llm/memory-manager/index.js +0 -107
  81. package/dist/llm/orchestrator/context.d.ts +0 -2
  82. package/dist/llm/orchestrator/context.js +0 -23
  83. package/dist/llm/orchestrator/index.d.ts +0 -44
  84. package/dist/llm/orchestrator/index.js +0 -139
  85. package/dist/llm/orchestrator/types.d.ts +0 -12
  86. package/dist/memory/cache.d.ts +0 -22
  87. package/dist/memory/cache.js +0 -165
  88. package/dist/memory/persistent.d.ts +0 -57
  89. package/dist/memory/persistent.js +0 -189
  90. package/dist/services/queue.d.ts +0 -13
  91. package/dist/services/redis-cache.d.ts +0 -37
  92. package/dist/services/redis-cache.js +0 -93
  93. package/dist/services/scheduler.d.ts +0 -40
  94. package/dist/services/scheduler.js +0 -99
  95. package/dist/services/telegram-monitor.d.ts +0 -0
  96. package/dist/services/telegram-monitor.js +0 -118
  97. package/dist/t.d.ts +0 -46
  98. package/dist/t.js +0 -102
  99. package/dist/test.d.ts +0 -0
  100. package/dist/test.js +0 -438
  101. package/dist/types.d.ts +0 -258
  102. package/dist/types.js +0 -22
  103. package/dist/utils/generate-object.d.ts +0 -12
  104. package/dist/utils/header-builder.d.ts +0 -11
  105. package/dist/utils/inject-actions.d.ts +0 -2
  106. package/dist/utils/queue-item-transformer.d.ts +0 -7
  107. package/dist/utils/sanitize-results.d.ts +0 -17
  108. package/dist/utils/schema-generator.d.ts +0 -16
  109. package/examples/actions/get-rss.ts +0 -71
  110. package/examples/index.ts +0 -98
  111. package/index.html +0 -42
  112. package/llm/dynamic-condition/example.ts +0 -36
  113. package/llm/dynamic-condition/index.ts +0 -108
  114. package/llm/interpreter/context.ts +0 -94
  115. package/llm/interpreter/index.ts +0 -140
  116. package/llm/memory-manager/context.ts +0 -19
  117. package/llm/memory-manager/index.ts +0 -115
  118. package/llm/orchestrator/context.ts +0 -19
  119. package/llm/orchestrator/index.ts +0 -192
  120. package/llm/orchestrator/types.ts +0 -14
  121. package/memory/cache.ts +0 -221
  122. package/memory/persistent.ts +0 -265
  123. package/script.js +0 -167
  124. package/services/cache.ts +0 -298
  125. package/services/telegram-monitor.ts +0 -138
  126. package/t.py +0 -79
  127. package/t.ts +0 -25
  128. package/test/llm/orchestrator.test.ts +0 -47
  129. package/test/llm/synthesizer.test.ts +0 -31
  130. package/types.ts +0 -367
  131. /package/dist/{llm/orchestrator/types.js → interfaces/index.js} +0 -0
@@ -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.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -24,6 +24,7 @@
24
24
  "readline": "^1.3.0",
25
25
  "redis": "^4.7.0",
26
26
  "rss-parser": "^3.13.0",
27
+ "sinon": "^19.0.2",
27
28
  "ws": "^8.18.0",
28
29
  "zod": "^3.24.1"
29
30
  },
@@ -31,12 +32,16 @@
31
32
  "@jest/globals": "^29.7.0",
32
33
  "@types/chai": "^4.3.20",
33
34
  "@types/mocha": "^10.0.0",
35
+ "@types/sinon": "^17.0.3",
34
36
  "@types/ws": "^8.5.14",
35
37
  "chai": "^4.5.0",
36
38
  "mocha": "^10.0.0",
37
39
  "ts-node": "^10.9.0",
38
40
  "tsconfig-paths": "^4.2.0",
39
- "typescript": "^5.7.2"
41
+ "typescript": "^5.7.2",
42
+ "meilisearch": "^0.37.0",
43
+ "redis": "^4.6.13",
44
+ "dotenv": "^16.4.5"
40
45
  },
41
46
  "repository": {
42
47
  "type": "git",
@@ -1,25 +1,9 @@
1
+ import { ScheduledRequest } from "@/types";
1
2
  import cron from "node-cron";
2
- import { Orchestrator } from "../llm/orchestrator";
3
- import { RedisCache } from "./cache";
4
-
5
- interface ScheduledRequest {
6
- id: string;
7
- originalRequest: string;
8
- cronExpression: string;
9
- isRecurring: boolean;
10
- createdAt: Date;
11
- }
12
3
 
13
4
  export class Agenda {
14
5
  private scheduledRequests: Map<string, ScheduledRequest> = new Map();
15
6
  private cronJobs: Map<string, cron.ScheduledTask> = new Map();
16
- private readonly orchestrator: Orchestrator;
17
- private readonly cache: RedisCache;
18
-
19
- constructor(orchestrator: Orchestrator, cache: RedisCache) {
20
- this.orchestrator = orchestrator;
21
- this.cache = cache;
22
- }
23
7
 
24
8
  /**
25
9
  * Schedule a new request to be processed later
@@ -45,39 +29,34 @@ export class Agenda {
45
29
  };
46
30
 
47
31
  // Create cron job
48
- const cronJob = cron.schedule(request.cronExpression, async () => {
49
- await this.executeScheduledRequest(scheduledRequest);
32
+ const cronJob = cron.schedule(request.cronExpression, () => {
33
+ console.log(`🔄 Executing scheduled request: ${id}`);
50
34
 
51
- if (callbacks?.onExecuted)
35
+ if (callbacks?.onExecuted) {
52
36
  callbacks.onExecuted(id, scheduledRequest.originalRequest);
37
+ }
38
+
39
+ console.log(`✅ Scheduled request executed successfully: ${id}`);
53
40
 
41
+ // Auto-stop pour les tâches non récurrentes
54
42
  if (!scheduledRequest.isRecurring) {
55
43
  this.cancelScheduledRequest(id);
56
44
  }
57
45
  });
58
46
 
47
+ // Démarrer le job en mode non-running
48
+ cronJob.stop();
49
+
59
50
  // Store request and job
60
51
  this.scheduledRequests.set(id, scheduledRequest);
61
52
  this.cronJobs.set(id, cronJob);
62
53
 
63
54
  if (callbacks?.onScheduled) callbacks.onScheduled(id);
64
55
 
65
- return id;
66
- }
56
+ // Démarrer le job après l'avoir stocké
57
+ cronJob.start();
67
58
 
68
- /**
69
- * Execute a scheduled request by launching a new process
70
- */
71
- private async executeScheduledRequest(
72
- request: ScheduledRequest
73
- ): Promise<void> {
74
- try {
75
- console.log(`🔄 Executing scheduled request from ${request.createdAt}`);
76
-
77
- console.log(`✅ Scheduled request executed successfully`);
78
- } catch (error) {
79
- console.error(`❌ Failed to execute scheduled request:`, error);
80
- }
59
+ return id;
81
60
  }
82
61
 
83
62
  /**
@@ -86,10 +65,17 @@ export class Agenda {
86
65
  cancelScheduledRequest(requestId: string): boolean {
87
66
  const cronJob = this.cronJobs.get(requestId);
88
67
  if (cronJob) {
89
- cronJob.stop();
90
- this.cronJobs.delete(requestId);
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
+ }
91
77
  }
92
- return this.scheduledRequests.delete(requestId);
78
+ return false;
93
79
  }
94
80
 
95
81
  /**
@@ -103,11 +89,30 @@ export class Agenda {
103
89
  * Stop all cron jobs
104
90
  */
105
91
  stopAll(): void {
106
- for (const [id, cronJob] of this.cronJobs) {
107
- cronJob.stop();
108
- this.cronJobs.delete(id);
109
- this.scheduledRequests.delete(id);
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
+ }
110
102
  }
111
- console.log("All scheduled requests stopped");
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));
112
117
  }
113
118
  }