@ai.ntellect/core 0.1.81 → 0.1.84
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/README.FR.md +31 -60
- package/README.md +74 -96
- package/agent/handlers/ActionHandler.ts +1 -1
- package/agent/index.ts +85 -43
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.js +61 -33
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/llm/evaluator/context.js +3 -5
- package/dist/llm/evaluator/index.js +25 -29
- package/dist/llm/orchestrator/context.js +1 -1
- package/dist/llm/orchestrator/index.js +30 -9
- package/dist/llm/synthesizer/index.d.ts +1 -5
- package/dist/llm/synthesizer/index.js +1 -5
- package/dist/memory/cache.d.ts +5 -5
- package/dist/memory/cache.js +19 -49
- package/dist/memory/persistent.d.ts +1 -1
- package/dist/memory/persistent.js +5 -6
- package/dist/services/queue.js +21 -8
- package/dist/t.d.ts +46 -0
- package/dist/t.js +102 -0
- package/dist/test.d.ts +68 -0
- package/dist/test.js +167 -0
- package/dist/types.d.ts +27 -3
- package/dist/types.js +9 -1
- package/dist/utils/inject-actions.js +1 -1
- package/dist/utils/queue-item-transformer.d.ts +2 -2
- package/dist/utils/queue-item-transformer.js +5 -6
- package/dist/utils/sanitize-results.d.ts +17 -0
- package/dist/utils/sanitize-results.js +60 -0
- package/index.ts +0 -1
- package/llm/evaluator/context.ts +3 -5
- package/llm/evaluator/index.ts +25 -31
- package/llm/orchestrator/context.ts +1 -1
- package/llm/orchestrator/index.ts +42 -13
- package/llm/synthesizer/index.ts +2 -10
- package/memory/cache.ts +23 -61
- package/memory/persistent.ts +7 -6
- package/package.json +3 -1
- package/services/queue.ts +21 -12
- package/t.ts +133 -0
- package/types.ts +14 -3
- package/utils/inject-actions.ts +1 -1
- package/utils/queue-item-transformer.ts +25 -11
- package/utils/sanitize-results.ts +66 -0
package/llm/evaluator/index.ts
CHANGED
@@ -20,24 +20,18 @@ export class Evaluator {
|
|
20
20
|
const response = await generateObject({
|
21
21
|
model: this.model,
|
22
22
|
schema: z.object({
|
23
|
-
|
24
|
-
|
25
|
-
name: z.string(),
|
26
|
-
parameters: z.object({
|
27
|
-
name: z.string(),
|
28
|
-
value: z.string(),
|
29
|
-
}),
|
30
|
-
})
|
31
|
-
),
|
32
|
-
why: z.string(),
|
33
|
-
isImportantToRemember: z.boolean(),
|
34
|
-
importantToRemembers: z.array(
|
23
|
+
isRemindNeeded: z.boolean(),
|
24
|
+
extraInformationsToRemember: z.array(
|
35
25
|
z.object({
|
36
26
|
memoryType: z.string(),
|
37
|
-
|
38
|
-
|
27
|
+
content: z.string(),
|
28
|
+
data: z.string(),
|
39
29
|
})
|
40
30
|
),
|
31
|
+
response: z.string(),
|
32
|
+
isNextActionNeeded: z.boolean(),
|
33
|
+
nextActionsNeeded: ActionSchema,
|
34
|
+
why: z.string(),
|
41
35
|
}),
|
42
36
|
prompt: prompt,
|
43
37
|
system: evaluatorContext.compose(goal, results, this.tools),
|
@@ -45,17 +39,17 @@ export class Evaluator {
|
|
45
39
|
|
46
40
|
const validatedResponse = {
|
47
41
|
...response.object,
|
48
|
-
nextActions: response.object.
|
42
|
+
nextActions: response.object.nextActionsNeeded.map((action) => ({
|
49
43
|
...action,
|
50
44
|
parameters: action.parameters || {},
|
51
45
|
})),
|
52
46
|
};
|
53
47
|
|
54
|
-
if (validatedResponse.
|
55
|
-
for (const item of validatedResponse.
|
48
|
+
if (validatedResponse.isRemindNeeded) {
|
49
|
+
for (const item of validatedResponse.extraInformationsToRemember) {
|
56
50
|
// Check if the item is already in the memory
|
57
51
|
const memories = await this.memory.searchSimilarQueries(
|
58
|
-
item.
|
52
|
+
item.content,
|
59
53
|
{
|
60
54
|
similarityThreshold: 95,
|
61
55
|
}
|
@@ -68,14 +62,14 @@ export class Evaluator {
|
|
68
62
|
}
|
69
63
|
if (memories.length === 0) {
|
70
64
|
console.log("Adding to memory", {
|
71
|
-
query: item.
|
72
|
-
data: item.
|
65
|
+
query: item.content,
|
66
|
+
data: item.data,
|
73
67
|
});
|
74
|
-
await this.memory.
|
68
|
+
await this.memory.createMemory({
|
75
69
|
id: crypto.randomUUID(),
|
76
70
|
purpose: item.memoryType,
|
77
|
-
query: item.
|
78
|
-
data: item.
|
71
|
+
query: item.content,
|
72
|
+
data: item.data,
|
79
73
|
scope: MemoryScope.GLOBAL,
|
80
74
|
createdAt: new Date(),
|
81
75
|
});
|
@@ -91,22 +85,22 @@ export class Evaluator {
|
|
91
85
|
console.log("Evaluator error");
|
92
86
|
console.dir(error.value, { depth: null });
|
93
87
|
console.error(error.message);
|
94
|
-
if (error.value.
|
95
|
-
for (const item of error.value.
|
88
|
+
if (error.value.extraInformationsToRemember.length > 0) {
|
89
|
+
for (const item of error.value.extraInformationsToRemember) {
|
96
90
|
// Check if the item is already in the memory
|
97
91
|
const memories = await this.memory.searchSimilarQueries(
|
98
|
-
item.
|
92
|
+
item.content
|
99
93
|
);
|
100
94
|
if (memories.length === 0) {
|
101
95
|
console.log("Adding to memory", {
|
102
|
-
query: item.
|
103
|
-
data: item.
|
96
|
+
query: item.content,
|
97
|
+
data: item.data,
|
104
98
|
});
|
105
|
-
await this.memory.
|
99
|
+
await this.memory.createMemory({
|
106
100
|
id: crypto.randomUUID(),
|
107
101
|
purpose: "importantToRemember",
|
108
|
-
query: item.
|
109
|
-
data: item.
|
102
|
+
query: item.content,
|
103
|
+
data: item.data,
|
110
104
|
scope: MemoryScope.USER,
|
111
105
|
createdAt: new Date(),
|
112
106
|
});
|
@@ -6,7 +6,7 @@ export const orchestratorContext = {
|
|
6
6
|
guidelines: {
|
7
7
|
important: [
|
8
8
|
"If there is no action to do, you must answer in the 'answer' field.",
|
9
|
-
"If some parameters are not clear or missing, YOU MUST ask the user for them.",
|
9
|
+
"If some parameters are not clear or missing, don't add the action, YOU MUST ask the user for them.",
|
10
10
|
"ALWAYS use the same language as user request. (If it's English, use English, if it's French, use French, etc.)",
|
11
11
|
"For QUESTIONS or ANALYSIS, BEFORE executing ANY actions, you MUST search in memory for similar queries AS THE ONLY ACTION TO EXECUTE.",
|
12
12
|
],
|
@@ -1,9 +1,8 @@
|
|
1
1
|
import { openai } from "@ai-sdk/openai";
|
2
2
|
import { generateObject } from "ai";
|
3
3
|
import { z } from "zod";
|
4
|
-
import { CacheMemory } from "../../memory/cache";
|
5
4
|
import { PersistentMemory } from "../../memory/persistent";
|
6
|
-
import { ActionSchema, BaseLLM } from "../../types";
|
5
|
+
import { ActionSchema, BaseLLM, MemoryScopeType } from "../../types";
|
7
6
|
import { orchestratorContext } from "./context";
|
8
7
|
|
9
8
|
export class Orchestrator implements BaseLLM {
|
@@ -21,8 +20,46 @@ export class Orchestrator implements BaseLLM {
|
|
21
20
|
parameters: z.object({
|
22
21
|
query: z.string(),
|
23
22
|
}),
|
24
|
-
execute: async (
|
25
|
-
const memories = await this.memory.searchSimilarQueries(
|
23
|
+
execute: async ({ query }: { query: string }) => {
|
24
|
+
const memories = await this.memory.searchSimilarQueries(query, {
|
25
|
+
similarityThreshold: 95,
|
26
|
+
});
|
27
|
+
return memories;
|
28
|
+
},
|
29
|
+
},
|
30
|
+
{
|
31
|
+
name: "save_memory",
|
32
|
+
description: "Save relevant information in the internal knowledge base",
|
33
|
+
parameters: z.object({
|
34
|
+
query: z.string(),
|
35
|
+
memoryType: z.string(),
|
36
|
+
data: z.any(),
|
37
|
+
scope: z.string().default("GLOBAL").describe("GLOBAL or USER"),
|
38
|
+
userId: z.string(),
|
39
|
+
whyStored: z.string(),
|
40
|
+
}),
|
41
|
+
execute: async ({
|
42
|
+
query,
|
43
|
+
purpose,
|
44
|
+
data,
|
45
|
+
scope,
|
46
|
+
userId,
|
47
|
+
}: {
|
48
|
+
query: string;
|
49
|
+
purpose: string;
|
50
|
+
data: any;
|
51
|
+
scope: MemoryScopeType;
|
52
|
+
userId?: string;
|
53
|
+
}) => {
|
54
|
+
const memories = await this.memory.createMemory({
|
55
|
+
query,
|
56
|
+
purpose,
|
57
|
+
data,
|
58
|
+
scope,
|
59
|
+
userId,
|
60
|
+
createdAt: new Date(),
|
61
|
+
id: crypto.randomUUID(),
|
62
|
+
});
|
26
63
|
return memories;
|
27
64
|
},
|
28
65
|
},
|
@@ -34,15 +71,7 @@ export class Orchestrator implements BaseLLM {
|
|
34
71
|
const response = await generateObject({
|
35
72
|
model: this.model,
|
36
73
|
schema: z.object({
|
37
|
-
actions:
|
38
|
-
z.object({
|
39
|
-
name: z.string(),
|
40
|
-
parameters: z.object({
|
41
|
-
name: z.string(),
|
42
|
-
value: z.string(),
|
43
|
-
}),
|
44
|
-
})
|
45
|
-
),
|
74
|
+
actions: ActionSchema,
|
46
75
|
answer: z.string(),
|
47
76
|
}),
|
48
77
|
prompt: prompt,
|
package/llm/synthesizer/index.ts
CHANGED
@@ -14,11 +14,7 @@ export class Synthesizer implements BaseLLM {
|
|
14
14
|
| {
|
15
15
|
actions: {
|
16
16
|
name: string;
|
17
|
-
|
18
|
-
explain: {
|
19
|
-
how: string;
|
20
|
-
why: string;
|
21
|
-
};
|
17
|
+
reasoning: string;
|
22
18
|
}[];
|
23
19
|
response: string;
|
24
20
|
}
|
@@ -31,11 +27,7 @@ export class Synthesizer implements BaseLLM {
|
|
31
27
|
actions: z.array(
|
32
28
|
z.object({
|
33
29
|
name: z.string(),
|
34
|
-
|
35
|
-
explain: z.object({
|
36
|
-
how: z.string(),
|
37
|
-
why: z.string(),
|
38
|
-
}),
|
30
|
+
reasoning: z.string(),
|
39
31
|
})
|
40
32
|
),
|
41
33
|
response: z.string(),
|
package/memory/cache.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
import { openai } from "@ai-sdk/openai";
|
2
|
-
import { cosineSimilarity, embed
|
2
|
+
import { cosineSimilarity, embed } from "ai";
|
3
3
|
import { createClient } from "redis";
|
4
|
-
import { z } from "zod";
|
5
4
|
import {
|
6
5
|
CacheMemoryOptions,
|
7
6
|
CacheMemoryType,
|
@@ -56,22 +55,23 @@ export class CacheMemory {
|
|
56
55
|
private async storeMemory(memory: CacheMemoryType) {
|
57
56
|
const prefix = this.getMemoryKey(memory.scope, memory.userId);
|
58
57
|
const key = `${prefix}${memory.id}`;
|
59
|
-
await this.redis.set(key, JSON.stringify(memory), {
|
58
|
+
const result = await this.redis.set(key, JSON.stringify(memory), {
|
60
59
|
EX: this.CACHE_TTL,
|
61
60
|
});
|
61
|
+
console.log("Cache memory created: ", result);
|
62
62
|
}
|
63
63
|
|
64
|
-
async
|
64
|
+
async findSimilarQueries(
|
65
65
|
query: string,
|
66
66
|
options: MatchOptions & { userId?: string; scope?: MemoryScope } = {}
|
67
67
|
): Promise<
|
68
68
|
{
|
69
69
|
data: any;
|
70
70
|
similarityPercentage: number;
|
71
|
-
|
71
|
+
query: string;
|
72
72
|
}[]
|
73
73
|
> {
|
74
|
-
console.log("\
|
74
|
+
console.log("\nSearching in cache for query:", query);
|
75
75
|
|
76
76
|
const { embedding } = await embed({
|
77
77
|
model: openai.embedding("text-embedding-3-small"),
|
@@ -79,22 +79,16 @@ export class CacheMemory {
|
|
79
79
|
});
|
80
80
|
|
81
81
|
const memories = await this.getAllMemories(options.scope, options.userId);
|
82
|
-
console.log("\n📚 Found", memories.length, "
|
82
|
+
console.log("\n📚 Found", memories.length, "queries to compare with");
|
83
83
|
|
84
84
|
const matches = memories
|
85
85
|
.map((memory) => {
|
86
86
|
const similarity = cosineSimilarity(embedding, memory.embedding);
|
87
87
|
const similarityPercentage = (similarity + 1) * 50; // Conversion en pourcentage
|
88
|
-
|
89
|
-
console.log(`\n📊 Memory "${memory.purpose}":
|
90
|
-
- Similarity: ${similarityPercentage.toFixed(2)}%
|
91
|
-
- Query: ${memory.query}`);
|
92
|
-
|
93
88
|
return {
|
94
89
|
data: memory.data,
|
90
|
+
query: memory.query,
|
95
91
|
similarityPercentage,
|
96
|
-
purpose: memory.purpose,
|
97
|
-
// Optionnel : ajouter des métadonnées utiles
|
98
92
|
memoryId: memory.id,
|
99
93
|
};
|
100
94
|
})
|
@@ -109,21 +103,20 @@ export class CacheMemory {
|
|
109
103
|
: matches;
|
110
104
|
|
111
105
|
if (results.length > 0) {
|
112
|
-
console.log("\n✨
|
106
|
+
console.log("\n✨ Similar queries found:");
|
113
107
|
results.forEach((match) => {
|
114
108
|
console.log(
|
115
|
-
`- ${match.
|
109
|
+
`- ${match.query} (${match.similarityPercentage.toFixed(2)}%)`
|
116
110
|
);
|
117
111
|
});
|
118
112
|
} else {
|
119
113
|
console.log("No matches found");
|
120
114
|
}
|
121
115
|
|
122
|
-
console.dir({ results });
|
123
116
|
return results;
|
124
117
|
}
|
125
118
|
|
126
|
-
|
119
|
+
async getAllMemories(
|
127
120
|
scope?: MemoryScope,
|
128
121
|
userId?: string
|
129
122
|
): Promise<CacheMemoryType[]> {
|
@@ -161,67 +154,37 @@ export class CacheMemory {
|
|
161
154
|
|
162
155
|
public async createMemory(
|
163
156
|
input: CreateMemoryInput
|
164
|
-
): Promise<
|
165
|
-
|
157
|
+
): Promise<CacheMemoryType | undefined> {
|
158
|
+
console.log("Searching for similar memory", input);
|
159
|
+
const existingPattern = await this.findSimilarQueries(input.content, {
|
166
160
|
similarityThreshold: 95,
|
167
161
|
userId: input.userId,
|
168
162
|
scope: input.scope,
|
169
163
|
});
|
170
164
|
|
171
165
|
if (existingPattern.length > 0) {
|
172
|
-
console.log("\
|
166
|
+
console.log("\nSimilar cache memory found:");
|
173
167
|
existingPattern.forEach((match) => {
|
174
168
|
console.log(
|
175
|
-
`- ${match.
|
169
|
+
`- ${match.query} (${match.similarityPercentage.toFixed(2)}%)`
|
176
170
|
);
|
177
171
|
});
|
172
|
+
console.log("Cache memory already exists. No need to create new one..");
|
178
173
|
return;
|
179
174
|
}
|
180
175
|
|
181
|
-
|
182
|
-
const variations = await generateObject({
|
183
|
-
model: openai("gpt-4"),
|
184
|
-
schema: z.object({
|
185
|
-
request: z.string().describe("The request to be performed"),
|
186
|
-
queries: z.array(z.object({ text: z.string() })),
|
187
|
-
}),
|
188
|
-
prompt: `For this input: "${input.content}"
|
189
|
-
Generate similar variations that should match the same context.
|
190
|
-
Context type: ${input.type}
|
191
|
-
Data: ${JSON.stringify(input.data)}
|
192
|
-
- Keep variations natural and human-like
|
193
|
-
- Include the original input
|
194
|
-
- Add 3-5 variations`,
|
195
|
-
});
|
176
|
+
console.log("No similar memory found");
|
196
177
|
|
197
|
-
await this.createSingleMemory({
|
178
|
+
const memory = await this.createSingleMemory({
|
198
179
|
id: crypto.randomUUID(),
|
199
180
|
content: input.content,
|
200
181
|
type: input.type,
|
201
182
|
data: input.data,
|
202
|
-
purpose: variations.object.request,
|
203
183
|
userId: input.userId,
|
204
184
|
scope: input.scope,
|
205
185
|
});
|
206
186
|
|
207
|
-
|
208
|
-
async (variation) => {
|
209
|
-
if (variation.text !== input.content) {
|
210
|
-
await this.createSingleMemory({
|
211
|
-
id: crypto.randomUUID(),
|
212
|
-
content: variation.text,
|
213
|
-
type: input.type,
|
214
|
-
data: input.data,
|
215
|
-
purpose: variations.object.request,
|
216
|
-
userId: input.userId,
|
217
|
-
scope: input.scope,
|
218
|
-
});
|
219
|
-
}
|
220
|
-
}
|
221
|
-
);
|
222
|
-
|
223
|
-
await Promise.all(variationPromises);
|
224
|
-
return variations.object.request;
|
187
|
+
return memory;
|
225
188
|
}
|
226
189
|
|
227
190
|
private async createSingleMemory(params: {
|
@@ -229,20 +192,20 @@ export class CacheMemory {
|
|
229
192
|
content: string;
|
230
193
|
type: MemoryType;
|
231
194
|
data: any;
|
232
|
-
purpose: string;
|
233
195
|
userId?: string;
|
234
196
|
scope?: MemoryScope;
|
235
197
|
}): Promise<CacheMemoryType> {
|
198
|
+
console.log("Creating new cache memory...", params.content);
|
199
|
+
console.log("Creating embedding...");
|
236
200
|
const { embedding } = await embed({
|
237
201
|
model: openai.embedding("text-embedding-3-small"),
|
238
202
|
value: params.content,
|
239
203
|
});
|
240
|
-
|
204
|
+
console.log("Embedding created");
|
241
205
|
const memory: CacheMemoryType = {
|
242
206
|
id: params.id,
|
243
207
|
type: params.type,
|
244
208
|
data: params.data,
|
245
|
-
purpose: params.purpose,
|
246
209
|
query: params.content,
|
247
210
|
embedding,
|
248
211
|
userId: params.userId,
|
@@ -250,7 +213,6 @@ export class CacheMemory {
|
|
250
213
|
params.scope || (params.userId ? MemoryScope.USER : MemoryScope.GLOBAL),
|
251
214
|
createdAt: new Date(),
|
252
215
|
};
|
253
|
-
|
254
216
|
await this.storeMemory(memory);
|
255
217
|
return memory;
|
256
218
|
}
|
package/memory/persistent.ts
CHANGED
@@ -77,7 +77,6 @@ export class PersistentMemory {
|
|
77
77
|
options: RequestInit = {}
|
78
78
|
): Promise<T> {
|
79
79
|
const url = `${this.host}${path}`;
|
80
|
-
console.log("Making request to:", url);
|
81
80
|
const response = await fetch(url, {
|
82
81
|
...options,
|
83
82
|
headers: {
|
@@ -160,7 +159,7 @@ export class PersistentMemory {
|
|
160
159
|
/**
|
161
160
|
* Store a memory in the database
|
162
161
|
*/
|
163
|
-
async
|
162
|
+
async createMemory(memory: Memory) {
|
164
163
|
const indexName = this._getIndexName(memory.scope, memory.userId);
|
165
164
|
await this._getOrCreateIndex(indexName);
|
166
165
|
|
@@ -179,7 +178,7 @@ export class PersistentMemory {
|
|
179
178
|
body: JSON.stringify([document]),
|
180
179
|
}
|
181
180
|
);
|
182
|
-
console.log("Stored memory response:", response);
|
181
|
+
console.log("Stored persistent memory response:", response);
|
183
182
|
return response;
|
184
183
|
}
|
185
184
|
|
@@ -187,7 +186,7 @@ export class PersistentMemory {
|
|
187
186
|
* Find best matching memories
|
188
187
|
*/
|
189
188
|
async searchSimilarQueries(query: string, options: SearchOptions = {}) {
|
190
|
-
console.log("\
|
189
|
+
console.log("\nSearching in persistent memory:", query);
|
191
190
|
|
192
191
|
// Generate embedding for the query
|
193
192
|
const { embedding: queryEmbedding } = await embed({
|
@@ -240,7 +239,9 @@ export class PersistentMemory {
|
|
240
239
|
}
|
241
240
|
}
|
242
241
|
|
243
|
-
console.log(
|
242
|
+
console.log(
|
243
|
+
`📚 Found ${searchResults.length} queries in persistent memory`
|
244
|
+
);
|
244
245
|
|
245
246
|
// Process and filter results using cosine similarity
|
246
247
|
const results = searchResults
|
@@ -272,7 +273,7 @@ export class PersistentMemory {
|
|
272
273
|
|
273
274
|
// Log results
|
274
275
|
if (results.length > 0) {
|
275
|
-
console.log("\n✨
|
276
|
+
console.log("\n✨ Similar queries found in persistent memory:");
|
276
277
|
results.forEach((match) => {
|
277
278
|
console.log(
|
278
279
|
`- ${match.query} : ${match.similarityPercentage.toFixed(2)}% (${
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ai.ntellect/core",
|
3
|
-
"version": "0.1.
|
3
|
+
"version": "0.1.84",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"scripts": {
|
@@ -14,8 +14,10 @@
|
|
14
14
|
"dependencies": {
|
15
15
|
"@ai-sdk/openai": "1.0.6",
|
16
16
|
"ai": "^3.0.0",
|
17
|
+
"ethers": "^6.13.5",
|
17
18
|
"langchain": "^0.3.11",
|
18
19
|
"redis": "^4.7.0",
|
20
|
+
"rss-parser": "^3.13.0",
|
19
21
|
"zod": "^3.24.1"
|
20
22
|
},
|
21
23
|
"devDependencies": {
|
package/services/queue.ts
CHANGED
@@ -42,7 +42,6 @@ export class ActionQueueManager {
|
|
42
42
|
|
43
43
|
for (const action of this.queue) {
|
44
44
|
const actionConfig = this.actions.find((a) => a.name === action.name);
|
45
|
-
|
46
45
|
if (actionConfig?.confirmation?.requireConfirmation) {
|
47
46
|
// Wait for user confirmation before executing this action
|
48
47
|
const shouldProceed = await this.callbacks.onConfirmationRequired?.(
|
@@ -62,6 +61,7 @@ export class ActionQueueManager {
|
|
62
61
|
continue;
|
63
62
|
}
|
64
63
|
}
|
64
|
+
const parameters = this.formatArguments(action.parameters);
|
65
65
|
|
66
66
|
actionPromises.push(
|
67
67
|
this.executeAction(action)
|
@@ -72,7 +72,7 @@ export class ActionQueueManager {
|
|
72
72
|
.catch((error) => {
|
73
73
|
const result = {
|
74
74
|
name: action.name,
|
75
|
-
parameters
|
75
|
+
parameters,
|
76
76
|
result: null,
|
77
77
|
error: error.message || "Unknown error occurred",
|
78
78
|
};
|
@@ -98,7 +98,23 @@ export class ActionQueueManager {
|
|
98
98
|
|
99
99
|
private formatArguments(args: QueueItemParameter[]): Record<string, string> {
|
100
100
|
return args.reduce<Record<string, string>>((acc, arg) => {
|
101
|
-
|
101
|
+
try {
|
102
|
+
// Parse the JSON string if the value is a stringified JSON object
|
103
|
+
const parsedValue = JSON.parse(arg.value);
|
104
|
+
if (
|
105
|
+
parsedValue &&
|
106
|
+
typeof parsedValue === "object" &&
|
107
|
+
"value" in parsedValue
|
108
|
+
) {
|
109
|
+
acc[parsedValue.name] = parsedValue.value;
|
110
|
+
} else {
|
111
|
+
// Fallback to original value if not in expected format
|
112
|
+
acc[arg.name] = arg.value;
|
113
|
+
}
|
114
|
+
} catch {
|
115
|
+
// If JSON parsing fails, use the original value
|
116
|
+
acc[arg.name] = arg.value;
|
117
|
+
}
|
102
118
|
return acc;
|
103
119
|
}, {});
|
104
120
|
}
|
@@ -115,13 +131,7 @@ export class ActionQueueManager {
|
|
115
131
|
error: `Action '${action.name}' not found in actions list`,
|
116
132
|
};
|
117
133
|
}
|
118
|
-
const actionArgs = action.parameters
|
119
|
-
(acc: Record<string, string>, arg: QueueItemParameter) => {
|
120
|
-
acc[arg.name] = arg.value;
|
121
|
-
return acc;
|
122
|
-
},
|
123
|
-
{}
|
124
|
-
);
|
134
|
+
const actionArgs = this.formatArguments(action.parameters);
|
125
135
|
try {
|
126
136
|
const result = await actionConfig.execute(actionArgs);
|
127
137
|
const actionResult = {
|
@@ -130,8 +140,7 @@ export class ActionQueueManager {
|
|
130
140
|
result,
|
131
141
|
error: null,
|
132
142
|
};
|
133
|
-
console.log("Action executed successfully: ", action.name);
|
134
|
-
console.dir(actionResult, { depth: null });
|
143
|
+
console.log("Action executed successfully: ", action.name, "🎉");
|
135
144
|
return actionResult;
|
136
145
|
} catch (error) {
|
137
146
|
const actionResult = {
|
package/t.ts
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
export interface NetworkConfig {
|
2
|
+
name: string;
|
3
|
+
id?: number;
|
4
|
+
rpc: string;
|
5
|
+
explorerUrl: string;
|
6
|
+
nativeToken: string; // WETH
|
7
|
+
}
|
8
|
+
export const networkConfigs: Record<string, NetworkConfig> = {
|
9
|
+
ethereum: {
|
10
|
+
name: "Ethereum Mainnet",
|
11
|
+
id: 1,
|
12
|
+
rpc: "https://eth.llamarpc.com",
|
13
|
+
explorerUrl: "https://etherscan.io",
|
14
|
+
nativeToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
15
|
+
},
|
16
|
+
polygon: {
|
17
|
+
name: "Polygon Mainnet",
|
18
|
+
id: 137,
|
19
|
+
rpc: "https://polygon.llamarpc.com",
|
20
|
+
explorerUrl: "https://polygonscan.com",
|
21
|
+
nativeToken: "0x0000000000000000000000000000000000001010",
|
22
|
+
},
|
23
|
+
arbitrum: {
|
24
|
+
name: "Arbitrum Mainnet",
|
25
|
+
id: 42161,
|
26
|
+
rpc: "https://arbitrum.llamarpc.com",
|
27
|
+
explorerUrl: "https://arbiscan.io",
|
28
|
+
nativeToken: "0x82af49447d8a07e3bd95bd0d56f35241523fbab1",
|
29
|
+
},
|
30
|
+
base: {
|
31
|
+
name: "Base Mainnet",
|
32
|
+
id: 8453,
|
33
|
+
rpc: "https://base.llamarpc.com",
|
34
|
+
explorerUrl: "https://basescan.org",
|
35
|
+
nativeToken: "0x4200000000000000000000000000000000000006",
|
36
|
+
},
|
37
|
+
solana: {
|
38
|
+
name: "Solana Mainnet",
|
39
|
+
rpc: "https://api.mainnet-beta.solana.com",
|
40
|
+
explorerUrl: "https://solscan.io",
|
41
|
+
nativeToken: "So11111111111111111111111111111111111111112",
|
42
|
+
},
|
43
|
+
sepolia: {
|
44
|
+
name: "Sepolia Testnet",
|
45
|
+
id: 11155111,
|
46
|
+
rpc: "https://sepolia.llamarpc.com",
|
47
|
+
explorerUrl: "https://sepolia.etherscan.io",
|
48
|
+
nativeToken: "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14",
|
49
|
+
},
|
50
|
+
baseSepolia: {
|
51
|
+
name: "Base Sepolia Testnet",
|
52
|
+
id: 84532,
|
53
|
+
rpc: "https://base-sepolia-rpc.publicnode.com",
|
54
|
+
explorerUrl: "https://sepolia.basescan.org",
|
55
|
+
nativeToken: "0x4200000000000000000000000000000000000006",
|
56
|
+
},
|
57
|
+
};
|
58
|
+
|
59
|
+
export const getNetworkProvider = (networkName: string) => {
|
60
|
+
const config = networkConfigs[networkName.toLowerCase()];
|
61
|
+
if (!config) {
|
62
|
+
throw new Error(`Network ${networkName} not supported`);
|
63
|
+
}
|
64
|
+
return { config };
|
65
|
+
};
|
66
|
+
|
67
|
+
import { parseEther } from "ethers";
|
68
|
+
import { z } from "zod";
|
69
|
+
|
70
|
+
export type TransactionPrepared = {
|
71
|
+
to: string;
|
72
|
+
value: string;
|
73
|
+
data?: string;
|
74
|
+
chain: {
|
75
|
+
id: number;
|
76
|
+
rpc: string;
|
77
|
+
};
|
78
|
+
type: "transfer" | "approve" | "swap";
|
79
|
+
method?: string;
|
80
|
+
params?: any[];
|
81
|
+
};
|
82
|
+
|
83
|
+
export const prepareEvmTransaction = {
|
84
|
+
name: "prepare-evm-transaction",
|
85
|
+
description: "Prepare a transaction for the user to sign.",
|
86
|
+
parameters: z.object({
|
87
|
+
walletAddress: z.string(),
|
88
|
+
amount: z
|
89
|
+
.string()
|
90
|
+
.describe("Ask the user for the amount to send, if not specified"),
|
91
|
+
network: z
|
92
|
+
.string()
|
93
|
+
.describe(
|
94
|
+
"Examples networks: ethereum, arbitrum, base. IMPORTANT: You must respect the network name."
|
95
|
+
),
|
96
|
+
}),
|
97
|
+
execute: async ({
|
98
|
+
walletAddress,
|
99
|
+
amount,
|
100
|
+
network,
|
101
|
+
}: {
|
102
|
+
walletAddress: string;
|
103
|
+
amount: string;
|
104
|
+
network: string;
|
105
|
+
}): Promise<TransactionPrepared> => {
|
106
|
+
try {
|
107
|
+
console.log("💰 Preparing transaction", {
|
108
|
+
to: walletAddress,
|
109
|
+
amount,
|
110
|
+
network,
|
111
|
+
});
|
112
|
+
|
113
|
+
const networkConfig = networkConfigs[network.toLowerCase()];
|
114
|
+
|
115
|
+
if (!networkConfig) {
|
116
|
+
throw new Error(`Network ${network} not found`);
|
117
|
+
}
|
118
|
+
|
119
|
+
return {
|
120
|
+
to: walletAddress,
|
121
|
+
value: parseEther(amount).toString(),
|
122
|
+
chain: {
|
123
|
+
id: networkConfig.id || 0,
|
124
|
+
rpc: networkConfig.rpc,
|
125
|
+
},
|
126
|
+
type: "transfer",
|
127
|
+
};
|
128
|
+
} catch (error) {
|
129
|
+
console.error("💰 Error sending transaction:", error);
|
130
|
+
throw new Error("An error occurred while sending the transaction");
|
131
|
+
}
|
132
|
+
},
|
133
|
+
};
|