@ai.ntellect/core 0.3.1 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
package/dist/types.d.ts CHANGED
@@ -154,8 +154,7 @@ export interface Memory {
154
154
  query: string;
155
155
  purpose: string;
156
156
  data: any;
157
- scope: MemoryScopeType;
158
- userId?: string;
157
+ roomId: string;
159
158
  createdAt: Date;
160
159
  chunks?: MemoryChunk[];
161
160
  }
@@ -205,3 +204,24 @@ export interface TransformedQueueItem {
205
204
  name: string;
206
205
  parameters: QueueItemParameter[];
207
206
  }
207
+ export interface ScheduledAction {
208
+ id: string;
209
+ action: {
210
+ name: string;
211
+ parameters: QueueItemParameter[];
212
+ };
213
+ scheduledTime: Date;
214
+ userId: string;
215
+ status: "pending" | "completed" | "failed";
216
+ recurrence?: {
217
+ type: "daily" | "weekly" | "monthly";
218
+ interval: number;
219
+ };
220
+ }
221
+ export interface ScheduledActionEvents {
222
+ onActionStart?: (action: ScheduledAction) => void;
223
+ onActionComplete?: (action: ScheduledAction, result: any) => void;
224
+ onActionFailed?: (action: ScheduledAction, error: Error) => void;
225
+ onActionScheduled?: (action: ScheduledAction) => void;
226
+ onActionCancelled?: (actionId: string) => void;
227
+ }
@@ -3,7 +3,7 @@ import { generateObject } from "ai";
3
3
  import { z } from "zod";
4
4
  import { CacheMemory } from "../../memory/cache";
5
5
  import { PersistentMemory } from "../../memory/persistent";
6
- import { ActionSchema, MemoryScope, MemoryType, State } from "../../types";
6
+ import { ActionSchema, MemoryType, State } from "../../types";
7
7
  import { injectActions } from "../../utils/inject-actions";
8
8
  import { Interpreter } from "../interpreter";
9
9
  import { evaluatorContext } from "./context";
@@ -129,7 +129,7 @@ export class Evaluator {
129
129
  purpose: item.memoryType,
130
130
  query: item.queryForData,
131
131
  data: item.data,
132
- scope: MemoryScope.GLOBAL,
132
+ roomId: "global",
133
133
  createdAt: new Date(),
134
134
  });
135
135
  }
@@ -142,7 +142,6 @@ export class Evaluator {
142
142
  content: prompt,
143
143
  type: MemoryType.ACTION,
144
144
  data: validatedResponse.actionsAlreadyDone,
145
- scope: MemoryScope.GLOBAL,
146
145
  });
147
146
  console.log(
148
147
  "✅ Workflow actions completed stored in cache",
@@ -177,7 +176,7 @@ export class Evaluator {
177
176
  purpose: "importantToRemember",
178
177
  query: item.content,
179
178
  data: item.data,
180
- scope: MemoryScope.GLOBAL,
179
+ roomId: "global",
181
180
  createdAt: new Date(),
182
181
  });
183
182
  }
package/memory/cache.ts CHANGED
@@ -44,15 +44,8 @@ export class CacheMemory {
44
44
  }
45
45
  }
46
46
 
47
- private getMemoryKey(scope: MemoryScope, userId?: string): string {
48
- if (scope === MemoryScope.GLOBAL) {
49
- return `${this.CACHE_PREFIX}global:`;
50
- }
51
- return `${this.CACHE_PREFIX}user:${userId}:`;
52
- }
53
-
54
47
  private async storeMemory(memory: CacheMemoryType) {
55
- const prefix = this.getMemoryKey(memory.scope, memory.userId);
48
+ const prefix = this.CACHE_PREFIX;
56
49
  const key = `${prefix}${memory.id}`;
57
50
  const result = await this.redis.set(key, JSON.stringify(memory), {
58
51
  EX: this.CACHE_TTL,
@@ -124,23 +117,10 @@ export class CacheMemory {
124
117
  scope?: MemoryScope,
125
118
  userId?: string
126
119
  ): Promise<CacheMemoryType[]> {
127
- let patterns: CacheMemoryType[] = [];
128
-
129
- if (!scope || scope === MemoryScope.GLOBAL) {
130
- const globalPrefix = this.getMemoryKey(MemoryScope.GLOBAL);
131
- const globalKeys = await this.redis.keys(`${globalPrefix}*`);
132
- const globalPatterns = await this.getMemoriesFromKeys(globalKeys);
133
- patterns = patterns.concat(globalPatterns);
134
- }
135
-
136
- if (userId && (!scope || scope === MemoryScope.USER)) {
137
- const userPrefix = this.getMemoryKey(MemoryScope.USER, userId);
138
- const userKeys = await this.redis.keys(`${userPrefix}*`);
139
- const userPatterns = await this.getMemoriesFromKeys(userKeys);
140
- patterns = patterns.concat(userPatterns);
141
- }
120
+ const keys = await this.redis.keys(`${this.CACHE_PREFIX}*`);
121
+ const memories = await this.getMemoriesFromKeys(keys);
142
122
 
143
- return patterns;
123
+ return memories;
144
124
  }
145
125
 
146
126
  private async getMemoriesFromKeys(
@@ -28,18 +28,6 @@ interface MeilisearchResponse {
28
28
  }>;
29
29
  }
30
30
 
31
- interface SearchParams {
32
- q?: string;
33
- offset?: number;
34
- limit?: number;
35
- filter?: string | string[];
36
- facets?: string[];
37
- attributesToRetrieve?: string[];
38
- attributesToSearchOn?: string[];
39
- sort?: string[];
40
- matchingStrategy?: "last" | "all" | "frequency";
41
- }
42
-
43
31
  interface ProcessedChunk {
44
32
  content: string;
45
33
  embedding: number[];
@@ -56,7 +44,7 @@ export class PersistentMemory {
56
44
  constructor(options: { host: string; apiKey: string; indexPrefix?: string }) {
57
45
  this.host = options.host;
58
46
  this.apiKey = options.apiKey;
59
- this.INDEX_PREFIX = options.indexPrefix || "memory_";
47
+ this.INDEX_PREFIX = options.indexPrefix || "memory";
60
48
  }
61
49
 
62
50
  /**
@@ -64,10 +52,7 @@ export class PersistentMemory {
64
52
  */
65
53
  async init() {
66
54
  // Create global index
67
- await this._getOrCreateIndex(this._getIndexName(MemoryScope.GLOBAL));
68
-
69
- // Create user index
70
- await this._getOrCreateIndex(this._getIndexName(MemoryScope.USER));
55
+ await this._getOrCreateIndex(this.INDEX_PREFIX);
71
56
  }
72
57
 
73
58
  /**
@@ -94,17 +79,6 @@ export class PersistentMemory {
94
79
 
95
80
  return response.json() as Promise<T>;
96
81
  }
97
-
98
- /**
99
- * Get index name based on scope and userId
100
- */
101
- private _getIndexName(scope: MemoryScope, userId?: string): string {
102
- if (scope === "global") {
103
- return `${this.INDEX_PREFIX}global`;
104
- }
105
- return `${this.INDEX_PREFIX}user_${userId}`;
106
- }
107
-
108
82
  /**
109
83
  * Get or create an index with proper settings
110
84
  */
@@ -161,8 +135,7 @@ export class PersistentMemory {
161
135
  * Store a memory in the database
162
136
  */
163
137
  async createMemory(memory: Memory) {
164
- const indexName = this._getIndexName(memory.scope, memory.userId);
165
- await this._getOrCreateIndex(indexName);
138
+ await this._getOrCreateIndex(memory.roomId);
166
139
 
167
140
  const chunks = await this.processContent(memory.data);
168
141
 
@@ -173,7 +146,7 @@ export class PersistentMemory {
173
146
  };
174
147
 
175
148
  const response = await this._makeRequest(
176
- `/indexes/${indexName}/documents`,
149
+ `/indexes/${this.INDEX_PREFIX}/documents`,
177
150
  {
178
151
  method: "POST",
179
152
  body: JSON.stringify([document]),
@@ -199,42 +172,20 @@ export class PersistentMemory {
199
172
 
200
173
  const searchResults = [];
201
174
 
202
- // Search in global memories
203
- if (!options.scope || options.scope === "global") {
204
- const globalIndex = this._getIndexName(MemoryScope.GLOBAL);
205
- console.log("\n📚 Searching in global index:", globalIndex);
206
- try {
207
- const globalResults = await this._makeRequest<MeilisearchResponse>(
208
- `/indexes/${globalIndex}/search`,
209
- {
210
- method: "POST",
211
- body: JSON.stringify({ q: query }),
212
- }
213
- );
214
- if (globalResults?.hits) {
215
- searchResults.push(...globalResults.hits);
216
- }
217
- } catch (error) {
218
- console.error("❌ Error searching global index:", error);
219
- }
220
- }
221
-
222
- // Search in user memories
223
- if (
224
- options.userId &&
225
- (!options.scope || options.scope === MemoryScope.USER)
226
- ) {
227
- const userIndex = this._getIndexName(MemoryScope.USER, options.userId);
228
- const userResults = await this._makeRequest<MeilisearchResponse>(
229
- `/indexes/${userIndex}/search`,
175
+ console.log("\n📚 Searching in global index:", this.INDEX_PREFIX);
176
+ try {
177
+ const globalResults = await this._makeRequest<MeilisearchResponse>(
178
+ `/indexes/${this.INDEX_PREFIX}/search`,
230
179
  {
231
180
  method: "POST",
232
181
  body: JSON.stringify({ q: query }),
233
182
  }
234
183
  );
235
- if (userResults.hits) {
236
- searchResults.push(...userResults.hits);
184
+ if (globalResults?.hits) {
185
+ searchResults.push(...globalResults.hits);
237
186
  }
187
+ } catch (error) {
188
+ console.error("❌ Error searching global index:", error);
238
189
  }
239
190
 
240
191
  const totalResults = searchResults.length;
@@ -284,9 +235,8 @@ export class PersistentMemory {
284
235
  /**
285
236
  * Delete memories for a given scope and user
286
237
  */
287
- async deleteMemories(scope: MemoryScope, userId?: string) {
288
- const indexName = this._getIndexName(scope, userId);
289
- return this._makeRequest(`/indexes/${indexName}`, {
238
+ async deleteMemories() {
239
+ return this._makeRequest(`/indexes/${this.INDEX_PREFIX}`, {
290
240
  method: "DELETE",
291
241
  });
292
242
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai.ntellect/core",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -0,0 +1,167 @@
1
+ import { Orchestrator } from "../llm/orchestrator";
2
+ import { ActionSchema, ScheduledAction, ScheduledActionEvents } from "../types";
3
+ import { ActionQueueManager } from "./queue";
4
+
5
+ export class ActionScheduler {
6
+ private scheduledActions: Map<string, NodeJS.Timeout> = new Map();
7
+ private storage: ScheduledActionStorage;
8
+ private events: ScheduledActionEvents;
9
+
10
+ constructor(
11
+ private actionQueueManager: ActionQueueManager,
12
+ private orchestrator: Orchestrator,
13
+ events: ScheduledActionEvents = {}
14
+ ) {
15
+ this.storage = new ScheduledActionStorage();
16
+ this.events = events;
17
+ this.initializeScheduledActions();
18
+ }
19
+
20
+ async scheduleAction(
21
+ action: ActionSchema,
22
+ scheduledTime: Date,
23
+ userId: string,
24
+ recurrence?: ScheduledAction["recurrence"]
25
+ ): Promise<string> {
26
+ const scheduledAction: ScheduledAction = {
27
+ id: crypto.randomUUID(),
28
+ action: {
29
+ name: action.name,
30
+ parameters: [],
31
+ },
32
+ scheduledTime,
33
+ userId,
34
+ status: "pending",
35
+ recurrence,
36
+ };
37
+
38
+ await this.storage.saveScheduledAction(scheduledAction);
39
+ this.scheduleExecution(scheduledAction);
40
+ this.events.onActionScheduled?.(scheduledAction);
41
+
42
+ return scheduledAction.id;
43
+ }
44
+
45
+ private async initializeScheduledActions() {
46
+ const pendingActions = await this.storage.getPendingActions();
47
+ pendingActions.forEach((action) => this.scheduleExecution(action));
48
+ }
49
+
50
+ private scheduleExecution(scheduledAction: ScheduledAction) {
51
+ const now = new Date();
52
+ const delay = scheduledAction.scheduledTime.getTime() - now.getTime();
53
+
54
+ if (delay < 0) return;
55
+
56
+ const timeout = setTimeout(async () => {
57
+ try {
58
+ await this.executeScheduledAction(scheduledAction);
59
+
60
+ if (scheduledAction.recurrence) {
61
+ const nextExecutionTime = this.calculateNextExecutionTime(
62
+ scheduledAction.scheduledTime,
63
+ scheduledAction.recurrence
64
+ );
65
+ const actionSchema = this.orchestrator.tools.find(
66
+ (tool: ActionSchema) => tool.name === scheduledAction.action.name
67
+ );
68
+ if (actionSchema) {
69
+ await this.scheduleAction(
70
+ actionSchema,
71
+ nextExecutionTime,
72
+ scheduledAction.userId,
73
+ scheduledAction.recurrence
74
+ );
75
+ }
76
+ }
77
+ } catch (error) {
78
+ console.error(
79
+ `Failed to execute scheduled action ${scheduledAction.id}:`,
80
+ error
81
+ );
82
+ await this.storage.updateActionStatus(scheduledAction.id, "failed");
83
+ }
84
+ }, delay);
85
+
86
+ this.scheduledActions.set(scheduledAction.id, timeout);
87
+ }
88
+
89
+ private async executeScheduledAction(scheduledAction: ScheduledAction) {
90
+ try {
91
+ this.events.onActionStart?.(scheduledAction);
92
+
93
+ this.actionQueueManager.addToQueue({
94
+ name: scheduledAction.action.name,
95
+ parameters: scheduledAction.action.parameters,
96
+ });
97
+
98
+ const result = await this.actionQueueManager.processQueue();
99
+ await this.storage.updateActionStatus(scheduledAction.id, "completed");
100
+
101
+ this.events.onActionComplete?.(scheduledAction, result);
102
+ } catch (error) {
103
+ await this.storage.updateActionStatus(scheduledAction.id, "failed");
104
+ this.events.onActionFailed?.(scheduledAction, error as Error);
105
+ throw error;
106
+ }
107
+ }
108
+
109
+ private calculateNextExecutionTime(
110
+ currentTime: Date,
111
+ recurrence: NonNullable<ScheduledAction["recurrence"]>
112
+ ): Date {
113
+ const nextTime = new Date(currentTime);
114
+
115
+ switch (recurrence.type) {
116
+ case "daily":
117
+ nextTime.setDate(nextTime.getDate() + recurrence.interval);
118
+ break;
119
+ case "weekly":
120
+ nextTime.setDate(nextTime.getDate() + 7 * recurrence.interval);
121
+ break;
122
+ case "monthly":
123
+ nextTime.setMonth(nextTime.getMonth() + recurrence.interval);
124
+ break;
125
+ }
126
+
127
+ return nextTime;
128
+ }
129
+
130
+ async cancelScheduledAction(actionId: string): Promise<boolean> {
131
+ const timeout = this.scheduledActions.get(actionId);
132
+ if (timeout) {
133
+ clearTimeout(timeout);
134
+ this.scheduledActions.delete(actionId);
135
+ await this.storage.deleteScheduledAction(actionId);
136
+ this.events.onActionCancelled?.(actionId);
137
+ return true;
138
+ }
139
+ return false;
140
+ }
141
+ }
142
+
143
+ class ScheduledActionStorage {
144
+ private actions: ScheduledAction[] = [];
145
+
146
+ async saveScheduledAction(action: ScheduledAction): Promise<void> {
147
+ this.actions.push(action);
148
+ }
149
+
150
+ async getPendingActions(): Promise<ScheduledAction[]> {
151
+ return this.actions.filter((action) => action.status === "pending");
152
+ }
153
+
154
+ async updateActionStatus(
155
+ actionId: string,
156
+ status: ScheduledAction["status"]
157
+ ): Promise<void> {
158
+ const action = this.actions.find((a) => a.id === actionId);
159
+ if (action) {
160
+ action.status = status;
161
+ }
162
+ }
163
+
164
+ async deleteScheduledAction(actionId: string): Promise<void> {
165
+ this.actions = this.actions.filter((a) => a.id !== actionId);
166
+ }
167
+ }
@@ -0,0 +1,138 @@
1
+ import dotenv from "dotenv";
2
+ import promptSync from "prompt-sync";
3
+ import { TelegramClient } from "telegram";
4
+ import { NewMessage } from "telegram/events";
5
+ import { StringSession } from "telegram/sessions";
6
+
7
+ dotenv.config();
8
+
9
+ const prompt = promptSync({ sigint: true });
10
+
11
+ export interface TokenLaunch {
12
+ tokenAddress: string;
13
+ messageUrl: string;
14
+ timestamp: string;
15
+ }
16
+
17
+ export class TelegramMonitor {
18
+ private client: TelegramClient;
19
+ private botStartTime: Date;
20
+
21
+ constructor() {
22
+ if (!process.env.TELEGRAM_API_ID || !process.env.TELEGRAM_API_HASH) {
23
+ throw new Error("TELEGRAM_API_ID and TELEGRAM_API_HASH must be set");
24
+ }
25
+ this.botStartTime = new Date();
26
+
27
+ const apiId = parseInt(process.env.TELEGRAM_API_ID);
28
+ const apiHash = process.env.TELEGRAM_API_HASH;
29
+
30
+ // Utiliser une session stockée si disponible
31
+ const sessionString = process.env.TELEGRAM_SESSION;
32
+ this.client = new TelegramClient(
33
+ new StringSession(sessionString),
34
+ apiId,
35
+ apiHash,
36
+ {
37
+ connectionRetries: 5,
38
+ }
39
+ );
40
+ }
41
+
42
+ async connect() {
43
+ // Se connecter en tant qu'utilisateur
44
+ await this.client.start({
45
+ phoneNumber: async () => prompt("Numéro de téléphone ? "),
46
+ password: async () => prompt("Mot de passe ? "),
47
+ phoneCode: async () => prompt("Code reçu ? "),
48
+ onError: (err) => console.log(err),
49
+ });
50
+
51
+ // Sauvegarder la session pour une utilisation ultérieure
52
+ console.log("Session string à sauvegarder:", this.client.session.save());
53
+ }
54
+
55
+ async startMonitoring(
56
+ channelUsername: string,
57
+ callback: {
58
+ onNewLaunch: (message: string) => void;
59
+ }
60
+ ) {
61
+ console.log(`Démarrage du monitoring pour ${channelUsername}`);
62
+
63
+ try {
64
+ // S'assurer que le client est connecté
65
+ if (!this.client.connected) {
66
+ console.log("Client non connecté, tentative de connexion...");
67
+ await this.client.connect();
68
+ console.log("Client connecté avec succès");
69
+ }
70
+
71
+ console.log("État de la connexion:", this.client.connected);
72
+
73
+ // Vérifier si le canal existe et est accessible
74
+ try {
75
+ const channel = await this.client.getEntity(channelUsername);
76
+ console.log("Canal trouvé:", channel.id);
77
+ } catch (e) {
78
+ console.error("Erreur lors de l'accès au canal:", e);
79
+ }
80
+
81
+ this.client.addEventHandler(async (event: any) => {
82
+ const message = event.message;
83
+ if (!message) {
84
+ console.log("Pas de message dans l'événement");
85
+ return;
86
+ }
87
+
88
+ if (!message.text) {
89
+ console.log("Message sans texte:", message);
90
+ return;
91
+ }
92
+
93
+ try {
94
+ callback.onNewLaunch(message.text);
95
+ } catch (error) {
96
+ console.error("Erreur lors du traitement du message:", error);
97
+ }
98
+ }, new NewMessage({ chats: [channelUsername] }));
99
+
100
+ console.log("Handler d'événements ajouté avec succès");
101
+ } catch (error) {
102
+ console.error("Erreur lors du démarrage du monitoring:", error);
103
+ }
104
+ }
105
+
106
+ static async generateNewSession() {
107
+ // Supprimer la session existante
108
+ const client = new TelegramClient(
109
+ new StringSession(""),
110
+ parseInt(process.env.TELEGRAM_API_ID || ""),
111
+ process.env.TELEGRAM_API_HASH || "",
112
+ {
113
+ connectionRetries: 5,
114
+ }
115
+ );
116
+
117
+ // Se connecter en tant qu'utilisateur
118
+ await client.start({
119
+ phoneNumber: async () => prompt("Numéro de téléphone ? "),
120
+ password: async () => prompt("Mot de passe ? "),
121
+ phoneCode: async () => prompt("Code reçu ? "),
122
+ onError: (err) => console.log(err),
123
+ });
124
+
125
+ // Sauvegarder la nouvelle session pour une utilisation ultérieure
126
+ console.log(
127
+ "Nouvelle session string à sauvegarder:",
128
+ client.session.save()
129
+ );
130
+ }
131
+ }
132
+
133
+ const telegramMonitor = new TelegramMonitor();
134
+ telegramMonitor.startMonitoring("testcalldegen", {
135
+ onNewLaunch: (message: string) => {
136
+ console.log("Nouveau message:", message);
137
+ },
138
+ });
package/types.ts CHANGED
@@ -188,8 +188,7 @@ export interface Memory {
188
188
  query: string;
189
189
  purpose: string;
190
190
  data: any;
191
- scope: MemoryScopeType;
192
- userId?: string;
191
+ roomId: string;
193
192
  createdAt: Date;
194
193
  chunks?: MemoryChunk[];
195
194
  }
@@ -231,3 +230,26 @@ export interface TransformedQueueItem {
231
230
  name: string;
232
231
  parameters: QueueItemParameter[];
233
232
  }
233
+
234
+ export interface ScheduledAction {
235
+ id: string;
236
+ action: {
237
+ name: string;
238
+ parameters: QueueItemParameter[];
239
+ };
240
+ scheduledTime: Date;
241
+ userId: string;
242
+ status: "pending" | "completed" | "failed";
243
+ recurrence?: {
244
+ type: "daily" | "weekly" | "monthly";
245
+ interval: number;
246
+ };
247
+ }
248
+
249
+ export interface ScheduledActionEvents {
250
+ onActionStart?: (action: ScheduledAction) => void;
251
+ onActionComplete?: (action: ScheduledAction, result: any) => void;
252
+ onActionFailed?: (action: ScheduledAction, error: Error) => void;
253
+ onActionScheduled?: (action: ScheduledAction) => void;
254
+ onActionCancelled?: (actionId: string) => void;
255
+ }