@ai.ntellect/core 0.1.81 → 0.1.84

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. package/README.FR.md +31 -60
  2. package/README.md +74 -96
  3. package/agent/handlers/ActionHandler.ts +1 -1
  4. package/agent/index.ts +85 -43
  5. package/dist/agent/index.d.ts +1 -1
  6. package/dist/agent/index.js +61 -33
  7. package/dist/index.d.ts +0 -1
  8. package/dist/index.js +0 -1
  9. package/dist/llm/evaluator/context.js +3 -5
  10. package/dist/llm/evaluator/index.js +25 -29
  11. package/dist/llm/orchestrator/context.js +1 -1
  12. package/dist/llm/orchestrator/index.js +30 -9
  13. package/dist/llm/synthesizer/index.d.ts +1 -5
  14. package/dist/llm/synthesizer/index.js +1 -5
  15. package/dist/memory/cache.d.ts +5 -5
  16. package/dist/memory/cache.js +19 -49
  17. package/dist/memory/persistent.d.ts +1 -1
  18. package/dist/memory/persistent.js +5 -6
  19. package/dist/services/queue.js +21 -8
  20. package/dist/t.d.ts +46 -0
  21. package/dist/t.js +102 -0
  22. package/dist/test.d.ts +68 -0
  23. package/dist/test.js +167 -0
  24. package/dist/types.d.ts +27 -3
  25. package/dist/types.js +9 -1
  26. package/dist/utils/inject-actions.js +1 -1
  27. package/dist/utils/queue-item-transformer.d.ts +2 -2
  28. package/dist/utils/queue-item-transformer.js +5 -6
  29. package/dist/utils/sanitize-results.d.ts +17 -0
  30. package/dist/utils/sanitize-results.js +60 -0
  31. package/index.ts +0 -1
  32. package/llm/evaluator/context.ts +3 -5
  33. package/llm/evaluator/index.ts +25 -31
  34. package/llm/orchestrator/context.ts +1 -1
  35. package/llm/orchestrator/index.ts +42 -13
  36. package/llm/synthesizer/index.ts +2 -10
  37. package/memory/cache.ts +23 -61
  38. package/memory/persistent.ts +7 -6
  39. package/package.json +3 -1
  40. package/services/queue.ts +21 -12
  41. package/t.ts +133 -0
  42. package/types.ts +14 -3
  43. package/utils/inject-actions.ts +1 -1
  44. package/utils/queue-item-transformer.ts +25 -11
  45. package/utils/sanitize-results.ts +66 -0
@@ -20,24 +20,18 @@ export class Evaluator {
20
20
  const response = await generateObject({
21
21
  model: this.model,
22
22
  schema: z.object({
23
- nextActions: z.array(
24
- z.object({
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
- hypotheticalQuery: z.string(),
38
- result: z.string(),
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.nextActions.map((action) => ({
42
+ nextActions: response.object.nextActionsNeeded.map((action) => ({
49
43
  ...action,
50
44
  parameters: action.parameters || {},
51
45
  })),
52
46
  };
53
47
 
54
- if (validatedResponse.isImportantToRemember) {
55
- for (const item of validatedResponse.importantToRemembers) {
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.hypotheticalQuery,
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.hypotheticalQuery,
72
- data: item.result,
65
+ query: item.content,
66
+ data: item.data,
73
67
  });
74
- await this.memory.storeMemory({
68
+ await this.memory.createMemory({
75
69
  id: crypto.randomUUID(),
76
70
  purpose: item.memoryType,
77
- query: item.hypotheticalQuery,
78
- data: item.result,
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.importantToRemembers.length > 0) {
95
- for (const item of error.value.importantToRemembers) {
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.hypotheticalQuery
92
+ item.content
99
93
  );
100
94
  if (memories.length === 0) {
101
95
  console.log("Adding to memory", {
102
- query: item.hypotheticalQuery,
103
- data: item.result,
96
+ query: item.content,
97
+ data: item.data,
104
98
  });
105
- await this.memory.storeMemory({
99
+ await this.memory.createMemory({
106
100
  id: crypto.randomUUID(),
107
101
  purpose: "importantToRemember",
108
- query: item.hypotheticalQuery,
109
- data: item.result,
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 (params) => {
25
- const memories = await this.memory.searchSimilarQueries(params.value);
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: z.array(
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,
@@ -14,11 +14,7 @@ export class Synthesizer implements BaseLLM {
14
14
  | {
15
15
  actions: {
16
16
  name: string;
17
- relevantResult: string;
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
- relevantResult: z.string(),
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, generateObject } from "ai";
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 findBestMatches(
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
- purpose: string;
71
+ query: string;
72
72
  }[]
73
73
  > {
74
- console.log("\n🔍 Searching in cache for query:", query);
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, "memories to compare with");
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✨ Best matches found:");
106
+ console.log("\n✨ Similar queries found:");
113
107
  results.forEach((match) => {
114
108
  console.log(
115
- `- ${match.purpose} (${match.similarityPercentage.toFixed(2)}%)`
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
- private async getAllMemories(
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<string | undefined> {
165
- const existingPattern = await this.findBestMatches(input.content, {
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("\n🔍 Similar memory found:");
166
+ console.log("\nSimilar cache memory found:");
173
167
  existingPattern.forEach((match) => {
174
168
  console.log(
175
- `- ${match.purpose} (${match.similarityPercentage.toFixed(2)}%)`
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
- // Générer les variations via GPT-4
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
- const variationPromises = variations.object.queries.map(
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
  }
@@ -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 storeMemory(memory: Memory) {
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("\n🔍 Searching in persistent memory:", query);
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("Found in persistent memory:", searchResults);
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✨ Best matches found:");
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.81",
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: this.formatArguments(action.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
- acc[arg.name] = arg.value;
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.reduce<Record<string, string>>(
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
+ };