@ai.ntellect/core 0.3.3 โ 0.4.1
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/.nvmrc +1 -0
- package/README.FR.md +242 -247
- package/README.md +249 -246
- package/agent/index.ts +199 -215
- package/agent/tools/get-rss.ts +64 -0
- package/bull.ts +5 -0
- package/dist/agent/index.d.ts +29 -26
- package/dist/agent/index.js +123 -112
- package/dist/agent/tools/get-rss.d.ts +16 -0
- package/dist/agent/tools/get-rss.js +62 -0
- package/dist/bull.d.ts +1 -0
- package/dist/bull.js +9 -0
- package/dist/examples/index.d.ts +2 -0
- package/dist/examples/index.js +89 -0
- package/dist/llm/interpreter/context.d.ts +5 -22
- package/dist/llm/interpreter/context.js +8 -9
- package/dist/llm/interpreter/index.d.ts +9 -5
- package/dist/llm/interpreter/index.js +55 -48
- package/dist/llm/memory-manager/context.d.ts +2 -0
- package/dist/llm/memory-manager/context.js +22 -0
- package/dist/llm/memory-manager/index.d.ts +17 -0
- package/dist/llm/memory-manager/index.js +107 -0
- package/dist/llm/orchestrator/context.d.ts +2 -10
- package/dist/llm/orchestrator/context.js +19 -14
- package/dist/llm/orchestrator/index.d.ts +36 -21
- package/dist/llm/orchestrator/index.js +122 -88
- package/dist/llm/orchestrator/types.d.ts +12 -0
- package/dist/llm/orchestrator/types.js +2 -0
- package/dist/memory/cache.d.ts +6 -5
- package/dist/memory/cache.js +31 -21
- package/dist/memory/persistent.d.ts +5 -3
- package/dist/memory/persistent.js +89 -73
- package/dist/services/redis-cache.d.ts +37 -0
- package/dist/services/redis-cache.js +93 -0
- package/dist/services/scheduler.d.ts +39 -16
- package/dist/services/scheduler.js +81 -103
- package/dist/services/telegram-monitor.d.ts +0 -15
- package/dist/services/telegram-monitor.js +117 -101
- package/dist/test.js +106 -172
- package/dist/types.d.ts +38 -7
- package/dist/utils/generate-object.d.ts +12 -0
- package/dist/utils/generate-object.js +90 -0
- package/dist/utils/header-builder.d.ts +11 -0
- package/dist/utils/header-builder.js +34 -0
- package/dist/utils/inject-actions.js +2 -2
- package/dist/utils/queue-item-transformer.d.ts +2 -2
- package/dist/utils/schema-generator.d.ts +16 -0
- package/dist/utils/schema-generator.js +46 -0
- package/examples/index.ts +103 -0
- package/llm/interpreter/context.ts +20 -8
- package/llm/interpreter/index.ts +81 -54
- package/llm/memory-manager/context.ts +21 -0
- package/llm/memory-manager/index.ts +163 -0
- package/llm/orchestrator/context.ts +20 -13
- package/llm/orchestrator/index.ts +210 -130
- package/llm/orchestrator/types.ts +14 -0
- package/memory/cache.ts +37 -31
- package/memory/persistent.ts +121 -99
- package/package.json +11 -2
- package/services/redis-cache.ts +128 -0
- package/services/scheduler.ts +102 -141
- package/services/telegram-monitor.ts +138 -138
- package/t.py +79 -0
- package/t.spec +38 -0
- package/types.ts +40 -7
- package/utils/generate-object.ts +105 -0
- package/utils/header-builder.ts +40 -0
- package/utils/inject-actions.ts +4 -6
- package/utils/queue-item-transformer.ts +2 -1
- package/utils/schema-generator.ts +73 -0
- package/agent/handlers/ActionHandler.ts +0 -48
- package/agent/handlers/ConfirmationHandler.ts +0 -37
- package/agent/handlers/EventHandler.ts +0 -35
- package/dist/agent/handlers/ActionHandler.d.ts +0 -8
- package/dist/agent/handlers/ActionHandler.js +0 -36
- package/dist/agent/handlers/ConfirmationHandler.d.ts +0 -7
- package/dist/agent/handlers/ConfirmationHandler.js +0 -31
- package/dist/agent/handlers/EventHandler.d.ts +0 -10
- package/dist/agent/handlers/EventHandler.js +0 -34
- package/dist/llm/evaluator/context.d.ts +0 -10
- package/dist/llm/evaluator/context.js +0 -24
- package/dist/llm/evaluator/index.d.ts +0 -16
- package/dist/llm/evaluator/index.js +0 -150
- package/llm/evaluator/context.ts +0 -21
- package/llm/evaluator/index.ts +0 -193
package/memory/persistent.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
import {
|
2
|
-
import { cosineSimilarity, embed, embedMany } from "ai";
|
1
|
+
import { cosineSimilarity, embed, EmbeddingModel, embedMany } from "ai";
|
3
2
|
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
|
4
|
-
import {
|
3
|
+
import { LongTermMemory, MemoryScope } from "../types";
|
5
4
|
|
6
5
|
interface SearchOptions {
|
7
6
|
scope?: MemoryScope;
|
@@ -40,19 +39,31 @@ export class PersistentMemory {
|
|
40
39
|
private readonly host: string;
|
41
40
|
private readonly apiKey: string;
|
42
41
|
private readonly INDEX_PREFIX: string;
|
43
|
-
|
44
|
-
constructor(options: {
|
42
|
+
private readonly embeddingModel: EmbeddingModel<string>;
|
43
|
+
constructor(options: {
|
44
|
+
host: string;
|
45
|
+
apiKey: string;
|
46
|
+
indexPrefix?: string;
|
47
|
+
embeddingModel: EmbeddingModel<string>;
|
48
|
+
}) {
|
45
49
|
this.host = options.host;
|
46
50
|
this.apiKey = options.apiKey;
|
47
51
|
this.INDEX_PREFIX = options.indexPrefix || "memory";
|
52
|
+
this.embeddingModel = options.embeddingModel;
|
48
53
|
}
|
49
54
|
|
50
55
|
/**
|
51
56
|
* Initialize indexes
|
52
57
|
*/
|
53
58
|
async init() {
|
54
|
-
|
55
|
-
|
59
|
+
try {
|
60
|
+
// Create or get main index
|
61
|
+
await this._getOrCreateIndex(this.INDEX_PREFIX);
|
62
|
+
console.log(`โ
Index '${this.INDEX_PREFIX}' initialized successfully`);
|
63
|
+
} catch (error) {
|
64
|
+
console.error(`โ Failed to initialize index: ${error}`);
|
65
|
+
throw error;
|
66
|
+
}
|
56
67
|
}
|
57
68
|
|
58
69
|
/**
|
@@ -63,6 +74,7 @@ export class PersistentMemory {
|
|
63
74
|
options: RequestInit = {}
|
64
75
|
): Promise<T> {
|
65
76
|
const url = `${this.host}${path}`;
|
77
|
+
console.log("๐ Making request to Meilisearch:", url);
|
66
78
|
const response = await fetch(url, {
|
67
79
|
...options,
|
68
80
|
headers: {
|
@@ -79,19 +91,27 @@ export class PersistentMemory {
|
|
79
91
|
|
80
92
|
return response.json() as Promise<T>;
|
81
93
|
}
|
94
|
+
|
82
95
|
/**
|
83
96
|
* Get or create an index with proper settings
|
84
97
|
*/
|
85
98
|
private async _getOrCreateIndex(indexName: string) {
|
86
99
|
try {
|
87
|
-
//
|
88
|
-
await this._makeRequest(
|
89
|
-
method: "
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
})
|
94
|
-
|
100
|
+
// Check if index exists first
|
101
|
+
const indexExists = await this._makeRequest(`/indexes/${indexName}`, {
|
102
|
+
method: "GET",
|
103
|
+
}).catch(() => false);
|
104
|
+
|
105
|
+
if (!indexExists) {
|
106
|
+
console.log(`Creating new index: ${indexName}`);
|
107
|
+
await this._makeRequest("/indexes", {
|
108
|
+
method: "POST",
|
109
|
+
body: JSON.stringify({
|
110
|
+
uid: indexName,
|
111
|
+
primaryKey: "id",
|
112
|
+
}),
|
113
|
+
});
|
114
|
+
}
|
95
115
|
|
96
116
|
// Update index settings
|
97
117
|
const settings: MeilisearchSettings = {
|
@@ -103,11 +123,11 @@ export class PersistentMemory {
|
|
103
123
|
method: "PATCH",
|
104
124
|
body: JSON.stringify(settings),
|
105
125
|
});
|
126
|
+
|
127
|
+
console.log(`Index ${indexName} configured successfully`);
|
106
128
|
} catch (error: any) {
|
107
|
-
|
108
|
-
|
109
|
-
throw error;
|
110
|
-
}
|
129
|
+
console.error(`Failed to configure index ${indexName}:`, error);
|
130
|
+
throw error;
|
111
131
|
}
|
112
132
|
}
|
113
133
|
|
@@ -120,7 +140,7 @@ export class PersistentMemory {
|
|
120
140
|
|
121
141
|
// Generate embeddings for all chunks
|
122
142
|
const { embeddings } = await embedMany({
|
123
|
-
model:
|
143
|
+
model: this.embeddingModel,
|
124
144
|
values: chunks.map((chunk) => chunk.pageContent),
|
125
145
|
});
|
126
146
|
|
@@ -134,102 +154,104 @@ export class PersistentMemory {
|
|
134
154
|
/**
|
135
155
|
* Store a memory in the database
|
136
156
|
*/
|
137
|
-
async createMemory(memory:
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
+
async createMemory(memory: LongTermMemory) {
|
158
|
+
try {
|
159
|
+
console.log(`๐ Creating memory in index: ${this.INDEX_PREFIX}`);
|
160
|
+
|
161
|
+
// Process content into chunks with embeddings
|
162
|
+
const chunks = await this.processContent(memory.data);
|
163
|
+
|
164
|
+
// Generate unique ID if not provided
|
165
|
+
const id = memory.id || crypto.randomUUID();
|
166
|
+
|
167
|
+
const document = {
|
168
|
+
...memory,
|
169
|
+
chunks,
|
170
|
+
createdAt: memory.createdAt.toISOString(),
|
171
|
+
};
|
172
|
+
|
173
|
+
const response = await this._makeRequest(
|
174
|
+
`/indexes/${this.INDEX_PREFIX}/documents`,
|
175
|
+
{
|
176
|
+
method: "POST",
|
177
|
+
body: JSON.stringify([document]),
|
178
|
+
}
|
179
|
+
);
|
180
|
+
|
181
|
+
console.log("โ
Memory created successfully", { id });
|
182
|
+
return response;
|
183
|
+
} catch (error) {
|
184
|
+
console.error("โ Failed to create memory:", error);
|
185
|
+
throw error;
|
186
|
+
}
|
157
187
|
}
|
158
188
|
|
159
189
|
/**
|
160
190
|
* Find best matching memories
|
161
191
|
*/
|
162
192
|
async findRelevantDocuments(query: string, options: SearchOptions = {}) {
|
163
|
-
console.log(
|
193
|
+
console.log(`\n๐ Searching in index: ${this.INDEX_PREFIX}`);
|
164
194
|
console.log("Query:", query);
|
165
|
-
console.log("Options:", JSON.stringify(options, null, 2));
|
166
|
-
|
167
|
-
// Generate embedding for the query
|
168
|
-
const { embedding: queryEmbedding } = await embed({
|
169
|
-
model: openai.embedding("text-embedding-3-small"),
|
170
|
-
value: query,
|
171
|
-
});
|
172
195
|
|
173
|
-
const searchResults = [];
|
174
|
-
|
175
|
-
console.log("\n๐ Searching in global index:", this.INDEX_PREFIX);
|
176
196
|
try {
|
177
|
-
|
197
|
+
// Generate embedding for the query
|
198
|
+
const { embedding: queryEmbedding } = await embed({
|
199
|
+
model: this.embeddingModel,
|
200
|
+
value: query,
|
201
|
+
});
|
202
|
+
|
203
|
+
// Search in the index
|
204
|
+
const searchResults = await this._makeRequest<MeilisearchResponse>(
|
178
205
|
`/indexes/${this.INDEX_PREFIX}/search`,
|
179
206
|
{
|
180
207
|
method: "POST",
|
181
|
-
body: JSON.stringify({
|
208
|
+
body: JSON.stringify({
|
209
|
+
q: query,
|
210
|
+
limit: options.maxResults || 10,
|
211
|
+
}),
|
182
212
|
}
|
183
213
|
);
|
184
|
-
|
185
|
-
|
214
|
+
|
215
|
+
if (!searchResults?.hits?.length) {
|
216
|
+
console.log("โ No matches found");
|
217
|
+
return [];
|
186
218
|
}
|
187
|
-
} catch (error) {
|
188
|
-
console.error("โ Error searching global index:", error);
|
189
|
-
}
|
190
219
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
(
|
215
|
-
match.similarityPercentage >= (options.similarityThreshold || 70)
|
216
|
-
)
|
217
|
-
.sort((a, b) => b.similarityPercentage - a.similarityPercentage);
|
218
|
-
|
219
|
-
// Log filtered results in a more structured way
|
220
|
-
if (results.length > 0) {
|
221
|
-
console.log("\nโจ Relevant matches found:");
|
222
|
-
console.log("โ".repeat(50));
|
223
|
-
|
224
|
-
results.forEach((match, index) => {
|
225
|
-
console.log(`\n${index + 1}. Match Details:`);
|
226
|
-
console.log(` Query: ${match.query}`);
|
227
|
-
});
|
228
|
-
} else {
|
229
|
-
console.log("\nโ No relevant matches found");
|
230
|
-
}
|
220
|
+
// Process and filter results using cosine similarity
|
221
|
+
const results = searchResults.hits
|
222
|
+
.flatMap((hit) => {
|
223
|
+
const chunkSimilarities = hit.chunks.map((chunk) => ({
|
224
|
+
query: hit.query,
|
225
|
+
data: hit.data,
|
226
|
+
similarityPercentage:
|
227
|
+
(cosineSimilarity(queryEmbedding, chunk.embedding) + 1) * 50,
|
228
|
+
createdAt: hit.createdAt,
|
229
|
+
}));
|
230
|
+
|
231
|
+
return chunkSimilarities.reduce(
|
232
|
+
(best, current) =>
|
233
|
+
current.similarityPercentage > best.similarityPercentage
|
234
|
+
? current
|
235
|
+
: best,
|
236
|
+
chunkSimilarities[0]
|
237
|
+
);
|
238
|
+
})
|
239
|
+
.filter(
|
240
|
+
(match) =>
|
241
|
+
match.similarityPercentage >= (options.similarityThreshold || 70)
|
242
|
+
)
|
243
|
+
.sort((a, b) => b.similarityPercentage - a.similarityPercentage);
|
231
244
|
|
232
|
-
|
245
|
+
console.log(`โจ Found ${results.length} relevant matches`);
|
246
|
+
return results.map((result) => ({
|
247
|
+
query: result.query,
|
248
|
+
data: result.data,
|
249
|
+
createdAt: result.createdAt,
|
250
|
+
}));
|
251
|
+
} catch (error) {
|
252
|
+
console.error("โ Search failed:", error);
|
253
|
+
return [];
|
254
|
+
}
|
233
255
|
}
|
234
256
|
|
235
257
|
/**
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ai.ntellect/core",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.4.1",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"scripts": {
|
@@ -12,18 +12,24 @@
|
|
12
12
|
"author": "Lorcann Rauzduel",
|
13
13
|
"license": "ISC",
|
14
14
|
"dependencies": {
|
15
|
+
"@ai-sdk/deepseek": "^0.1.0",
|
15
16
|
"@ai-sdk/openai": "1.0.6",
|
17
|
+
"@types/node-cron": "^3.0.11",
|
16
18
|
"ai": "^3.0.0",
|
17
19
|
"ethers": "^6.13.5",
|
18
20
|
"langchain": "^0.3.11",
|
21
|
+
"node-cron": "^3.0.3",
|
22
|
+
"readline": "^1.3.0",
|
19
23
|
"redis": "^4.7.0",
|
20
24
|
"rss-parser": "^3.13.0",
|
25
|
+
"ws": "^8.18.0",
|
21
26
|
"zod": "^3.24.1"
|
22
27
|
},
|
23
28
|
"devDependencies": {
|
24
29
|
"@jest/globals": "^29.7.0",
|
25
30
|
"@types/chai": "^4.3.20",
|
26
31
|
"@types/mocha": "^10.0.0",
|
32
|
+
"@types/ws": "^8.5.14",
|
27
33
|
"chai": "^4.5.0",
|
28
34
|
"mocha": "^10.0.0",
|
29
35
|
"ts-node": "^10.9.0",
|
@@ -37,5 +43,8 @@
|
|
37
43
|
"bugs": {
|
38
44
|
"url": "https://github.com/ai-ntellect/core/issues"
|
39
45
|
},
|
40
|
-
"homepage": "https://github.com/ai-ntellect/core#readme"
|
46
|
+
"homepage": "https://github.com/ai-ntellect/core#readme",
|
47
|
+
"bin": {
|
48
|
+
"wallet-assistant": "./dist/examples/index.js"
|
49
|
+
}
|
41
50
|
}
|
@@ -0,0 +1,128 @@
|
|
1
|
+
import Redis from "ioredis";
|
2
|
+
import cron from "node-cron";
|
3
|
+
|
4
|
+
export interface CacheConfig {
|
5
|
+
host: string;
|
6
|
+
port: number;
|
7
|
+
password?: string;
|
8
|
+
ttl?: number; // Time to live in seconds (default 30 minutes)
|
9
|
+
cleanupInterval?: string; // Cron expression (default every 30 minutes)
|
10
|
+
}
|
11
|
+
|
12
|
+
export class RedisCache {
|
13
|
+
private redis: Redis;
|
14
|
+
private readonly defaultTTL: number;
|
15
|
+
private readonly cleanupJob: cron.ScheduledTask;
|
16
|
+
|
17
|
+
constructor(config: CacheConfig) {
|
18
|
+
this.redis = new Redis({
|
19
|
+
host: config.host,
|
20
|
+
port: config.port,
|
21
|
+
password: config.password,
|
22
|
+
});
|
23
|
+
|
24
|
+
this.defaultTTL = config.ttl || 1800; // 30 minutes in seconds
|
25
|
+
|
26
|
+
// Setup cleanup job (default: every 30 minutes)
|
27
|
+
this.cleanupJob = cron.schedule(
|
28
|
+
config.cleanupInterval || "*/30 * * * *",
|
29
|
+
() => this.cleanup()
|
30
|
+
);
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Store previous actions for a specific request
|
35
|
+
*/
|
36
|
+
async storePreviousActions(requestId: string, actions: any[]): Promise<void> {
|
37
|
+
const key = `previous_actions:${requestId}`;
|
38
|
+
await this.redis.setex(
|
39
|
+
key,
|
40
|
+
this.defaultTTL,
|
41
|
+
JSON.stringify({
|
42
|
+
timestamp: new Date().toISOString(),
|
43
|
+
actions,
|
44
|
+
})
|
45
|
+
);
|
46
|
+
}
|
47
|
+
|
48
|
+
/**
|
49
|
+
* Get previous actions for a specific request
|
50
|
+
*/
|
51
|
+
async getPreviousActions(requestId: string): Promise<any[]> {
|
52
|
+
const key = `previous_actions:${requestId}`;
|
53
|
+
const data = await this.redis.get(key);
|
54
|
+
if (!data) return [];
|
55
|
+
|
56
|
+
const parsed = JSON.parse(data);
|
57
|
+
return parsed.actions;
|
58
|
+
}
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Store a recent message
|
62
|
+
*/
|
63
|
+
async storeRecentMessage(
|
64
|
+
message: string,
|
65
|
+
metadata?: Record<string, any>
|
66
|
+
): Promise<void> {
|
67
|
+
const id = crypto.randomUUID();
|
68
|
+
const key = `recent_messages:${id}`;
|
69
|
+
await this.redis.setex(
|
70
|
+
key,
|
71
|
+
this.defaultTTL,
|
72
|
+
JSON.stringify({
|
73
|
+
timestamp: new Date().toISOString(),
|
74
|
+
message,
|
75
|
+
metadata,
|
76
|
+
})
|
77
|
+
);
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* Get recent messages
|
82
|
+
*/
|
83
|
+
async getRecentMessages(limit: number = 10): Promise<any[]> {
|
84
|
+
const keys = await this.redis.keys("recent_messages:*");
|
85
|
+
if (!keys.length) return [];
|
86
|
+
|
87
|
+
const messages = await Promise.all(
|
88
|
+
keys.map(async (key) => {
|
89
|
+
const data = await this.redis.get(key);
|
90
|
+
return data ? JSON.parse(data) : null;
|
91
|
+
})
|
92
|
+
);
|
93
|
+
|
94
|
+
return messages
|
95
|
+
.filter(Boolean)
|
96
|
+
.sort(
|
97
|
+
(a, b) =>
|
98
|
+
new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
99
|
+
)
|
100
|
+
.slice(0, limit);
|
101
|
+
}
|
102
|
+
|
103
|
+
/**
|
104
|
+
* Cleanup expired keys
|
105
|
+
*/
|
106
|
+
private async cleanup(): Promise<void> {
|
107
|
+
console.log("๐งน Starting cache cleanup...");
|
108
|
+
try {
|
109
|
+
// Redis automatically removes expired keys
|
110
|
+
// This is just for logging purposes
|
111
|
+
const actionKeys = await this.redis.keys("previous_actions:*");
|
112
|
+
const messageKeys = await this.redis.keys("recent_messages:*");
|
113
|
+
console.log(
|
114
|
+
`Cache status: ${actionKeys.length} actions, ${messageKeys.length} messages`
|
115
|
+
);
|
116
|
+
} catch (error) {
|
117
|
+
console.error("โ Cache cleanup error:", error);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* Stop the cleanup job and close Redis connection
|
123
|
+
*/
|
124
|
+
async close(): Promise<void> {
|
125
|
+
this.cleanupJob.stop();
|
126
|
+
await this.redis.quit();
|
127
|
+
}
|
128
|
+
}
|