@ai.ntellect/core 0.2.7 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. package/README.FR.md +58 -19
  2. package/README.md +40 -17
  3. package/agent/index.ts +64 -36
  4. package/dist/agent/index.d.ts +12 -8
  5. package/dist/agent/index.js +42 -20
  6. package/dist/index.d.ts +2 -1
  7. package/dist/index.js +2 -1
  8. package/dist/llm/evaluator/context.d.ts +0 -1
  9. package/dist/llm/evaluator/context.js +3 -12
  10. package/dist/llm/evaluator/index.d.ts +9 -3
  11. package/dist/llm/evaluator/index.js +38 -26
  12. package/dist/llm/interpreter/context.d.ts +32 -0
  13. package/dist/llm/interpreter/context.js +90 -0
  14. package/dist/llm/interpreter/index.d.ts +17 -0
  15. package/dist/llm/{synthesizer → interpreter}/index.js +19 -29
  16. package/dist/llm/orchestrator/context.js +1 -1
  17. package/dist/llm/orchestrator/index.d.ts +9 -5
  18. package/dist/llm/orchestrator/index.js +6 -49
  19. package/dist/memory/cache.d.ts +2 -2
  20. package/dist/memory/cache.js +4 -5
  21. package/dist/memory/persistent.d.ts +1 -0
  22. package/dist/memory/persistent.js +2 -1
  23. package/dist/test.d.ts +54 -0
  24. package/dist/test.js +125 -20
  25. package/dist/types.d.ts +12 -13
  26. package/index.ts +2 -2
  27. package/llm/evaluator/context.ts +3 -12
  28. package/llm/evaluator/index.ts +59 -30
  29. package/llm/interpreter/context.ts +89 -0
  30. package/llm/{synthesizer → interpreter}/index.ts +21 -28
  31. package/llm/orchestrator/context.ts +1 -1
  32. package/llm/orchestrator/index.ts +16 -75
  33. package/memory/cache.ts +5 -6
  34. package/memory/persistent.ts +3 -1
  35. package/package.json +1 -1
  36. package/types.ts +13 -13
  37. package/dist/llm/synthesizer/context.d.ts +0 -15
  38. package/dist/llm/synthesizer/context.js +0 -71
  39. package/dist/llm/synthesizer/index.d.ts +0 -14
  40. package/llm/synthesizer/context.ts +0 -68
package/dist/test.js CHANGED
@@ -3,15 +3,113 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getRssNews = exports.getChainsTVL = exports.fetchMarkPrice = exports.prepareEvmTransaction = exports.getNetworkProvider = exports.networkConfigs = void 0;
6
+ exports.getRssNews = exports.getChainsTVL = exports.fetchMarkPrice = exports.prepareEvmTransaction = exports.getNetworkProvider = exports.networkConfigs = exports.checkHoneypot = void 0;
7
7
  const ccxt_1 = __importDefault(require("ccxt"));
8
8
  const ethers_1 = require("ethers");
9
9
  const rss_parser_1 = __importDefault(require("rss-parser"));
10
10
  const zod_1 = require("zod");
11
11
  const agent_1 = require("./agent");
12
+ const interpreter_1 = require("./llm/interpreter");
13
+ const context_1 = require("./llm/interpreter/context");
12
14
  const orchestrator_1 = require("./llm/orchestrator");
13
15
  const cache_1 = require("./memory/cache");
14
16
  const persistent_1 = require("./memory/persistent");
17
+ // Mapping des noms de chaînes vers leurs IDs
18
+ const CHAIN_IDS = {
19
+ ethereum: "1",
20
+ bsc: "56",
21
+ polygon: "137",
22
+ matic: "137",
23
+ avalanche: "43114",
24
+ avax: "43114",
25
+ fantom: "250",
26
+ ftm: "250",
27
+ arbitrum: "42161",
28
+ arb: "42161",
29
+ optimism: "10",
30
+ base: "8453",
31
+ zksync: "324",
32
+ solana: "solana",
33
+ sol: "solana",
34
+ };
35
+ exports.checkHoneypot = {
36
+ name: "check-honeypot",
37
+ description: `Analyze a token to detect if it is a honeypot. RESPECT THIS FORMAT FOR CHAIN NAME: ${CHAIN_IDS.toString()}`,
38
+ parameters: zod_1.z.object({
39
+ address: zod_1.z.string().describe("Address of the token"),
40
+ chainName: zod_1.z.string().describe("Chain name (default: eth)"),
41
+ }),
42
+ execute: async ({ address, chainName, }) => {
43
+ try {
44
+ const API_URL = "https://api.honeypot.is/v2/IsHoneypot";
45
+ const chainId = getChainId(chainName);
46
+ console.log("💰 Checking honeypot for token", {
47
+ address,
48
+ chainId,
49
+ });
50
+ if (chainId === "solana") {
51
+ return {
52
+ status: "error",
53
+ message: "L'analyse des tokens Solana n'est pas encore supportée. Cette fonctionnalité sera disponible prochainement.",
54
+ chain: {
55
+ name: "Solana",
56
+ id: "solana",
57
+ },
58
+ };
59
+ }
60
+ const queryParams = new URLSearchParams({
61
+ address: address,
62
+ ...(chainId && { chainId }),
63
+ ...{ simulateLiquidity: "true" },
64
+ });
65
+ const response = await fetch(`${API_URL}?${queryParams}`);
66
+ if (!response.ok) {
67
+ throw new Error(`Erreur API: ${response.status} ${response.statusText}`);
68
+ }
69
+ const data = await response.json();
70
+ const result = {
71
+ status: "success",
72
+ token: {
73
+ name: data.token.name,
74
+ symbol: data.token.symbol,
75
+ address: data.token.address,
76
+ holders: data.token.totalHolders,
77
+ },
78
+ risk: {
79
+ level: data.summary.risk,
80
+ score: data.summary.riskLevel,
81
+ flags: data.summary.flags || [],
82
+ },
83
+ analysis: {
84
+ isHoneypot: data.honeypotResult?.isHoneypot || false,
85
+ reason: data.honeypotResult?.honeypotReason || null,
86
+ buyTax: data.simulationResult?.buyTax || 0,
87
+ sellTax: data.simulationResult?.sellTax || 0,
88
+ holders: {
89
+ total: data.holderAnalysis?.holders || 0,
90
+ successful: data.holderAnalysis?.successful || 0,
91
+ failed: data.holderAnalysis?.failed || 0,
92
+ siphoned: data.holderAnalysis?.siphoned || 0,
93
+ },
94
+ },
95
+ chain: {
96
+ name: data.chain.name,
97
+ id: data.chain.id,
98
+ },
99
+ };
100
+ return result;
101
+ }
102
+ catch (error) {
103
+ throw error;
104
+ }
105
+ },
106
+ };
107
+ function getChainId(chainName) {
108
+ if (!chainName)
109
+ return undefined;
110
+ const normalizedChainName = chainName.toLowerCase();
111
+ return CHAIN_IDS[normalizedChainName];
112
+ }
15
113
  exports.networkConfigs = {
16
114
  ethereum: {
17
115
  name: "Ethereum Mainnet",
@@ -239,30 +337,37 @@ exports.getRssNews = {
239
337
  host: "http://localhost:7700",
240
338
  apiKey: "aSampleMasterKey",
241
339
  });
242
- const orchestrator = new orchestrator_1.Orchestrator("1", [exports.getRssNews, exports.getChainsTVL, exports.fetchMarkPrice, exports.prepareEvmTransaction], {
243
- persistent: memory,
244
- cache: cacheMemory,
340
+ const orchestrator = new orchestrator_1.Orchestrator({
341
+ id: "1",
342
+ tools: [],
343
+ memory: {
344
+ persistent: memory,
345
+ cache: cacheMemory,
346
+ },
245
347
  });
348
+ const securityInterpreter = new interpreter_1.Interpreter("security", context_1.securityInterpreterContext);
349
+ const marketInterpreter = new interpreter_1.Interpreter("market", context_1.marketInterpreterContext);
350
+ const generalInterpreter = new interpreter_1.Interpreter("general", context_1.generalInterpreterContext);
351
+ // const ccacheMemory = await cacheMemory.findSimilarActions(
352
+ // "le top 3 des chaines par TVL en DeFi",
353
+ // {
354
+ // similarityThreshold: 50,
355
+ // maxResults: 5,
356
+ // userId: "1",
357
+ // scope: MemoryScope.GLOBAL,
358
+ // }
359
+ // );
360
+ // console.log("✅ RECENT_ACTIONS: ", ccacheMemory);
246
361
  const agent = new agent_1.Agent({
247
- user: {
248
- id: "1",
249
- },
362
+ interpreters: [securityInterpreter, marketInterpreter, generalInterpreter],
250
363
  orchestrator,
251
- cacheMemory,
252
- persistentMemory: memory,
364
+ memory: {
365
+ persistent: memory,
366
+ cache: cacheMemory,
367
+ },
253
368
  stream: false,
254
369
  maxEvaluatorIteration: 1,
255
370
  });
256
- const prompt = "transfere 0.0001 eth to 0xf520cEd3b7FdA050a3A44486C160BEAb15ED3285 on ethereum";
257
- const context = prompt;
258
- // const save = await cacheMemory.createMemory({
259
- // content: prompt,
260
- // data: [],
261
- // scope: MemoryScope.GLOBAL,
262
- // type: MemoryType.ACTION,
263
- // });
264
- // consoleil.log({ save });
265
- // const memo = await cacheMemory.getAllMemories();
266
- // console.log({ memo });
371
+ const prompt = "c quoi le top 3 des chaines par TVL en DeFi";
267
372
  const result = await agent.process(prompt, {});
268
373
  })();
package/dist/types.d.ts CHANGED
@@ -45,24 +45,23 @@ export interface ProcessPromptCallbacks {
45
45
  onQueueComplete?: (actions: QueueResult[]) => void | Promise<void>;
46
46
  onConfirmationRequired?: (message: string) => Promise<boolean>;
47
47
  }
48
- export type State = {
49
- behavior: {
50
- role: string;
51
- language: string;
52
- guidelines: {
53
- important: string[];
54
- warnings: string[];
55
- steps?: string[];
56
- };
48
+ export type Behavior = {
49
+ role: string;
50
+ language: string;
51
+ guidelines: {
52
+ important: string[];
53
+ warnings: string[];
54
+ steps?: string[];
57
55
  };
58
- userRequest: string;
59
- actions: ActionSchema[];
60
- results: QueueResult[];
61
56
  examplesMessages?: {
62
57
  role: string;
63
58
  content: string;
64
59
  }[];
65
60
  };
61
+ export type State = {
62
+ userRequest: string;
63
+ results: string;
64
+ };
66
65
  export interface ActionSchema {
67
66
  name: string;
68
67
  description: string;
@@ -126,7 +125,7 @@ export interface CacheMemoryOptions {
126
125
  export interface CreateMemoryInput {
127
126
  content: any;
128
127
  type: MemoryType;
129
- data: QueueResult[];
128
+ data: string[];
130
129
  userId?: string;
131
130
  scope?: MemoryScope;
132
131
  }
package/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export * from "./agent";
2
+ export * from "./llm/interpreter";
3
+ export * from "./llm/interpreter/context";
2
4
  export * from "./llm/orchestrator";
3
- export * from "./llm/synthesizer";
4
-
5
5
  export * from "./types";
6
6
 
7
7
  export * from "./memory/cache";
@@ -6,23 +6,14 @@ export const evaluatorContext = {
6
6
  important: [
7
7
  "Verify if all required actions were executed successfully.",
8
8
  "Check if the results align with the initial goal.",
9
- "Identify and extract additional relevant information naturally during the process. Examples:",
10
- " - Link a token symbol (e.g., 'USDC') to its address (e.g., '0xA0b8...6EB48').",
11
- " - Associate a wallet address (e.g., '0x1234...abcd') to a user-friendly name (e.g., 'Work Wallet').",
12
- " - Map a token address (e.g., '0x6B17...71d0F') back to its symbol or name (e.g., 'DAI').",
13
- "Store these facts in memory with their type (episodic, semantic, or procedural).",
9
+ "If you retrieved the informations from your internal knowledge base, no need to store them in 'extraInformationsToStore'.",
10
+ "Store ONLY extra new needed informations in 'extraInformationsToStore' (choose the most relevant informations and memory type: episodic, semantic, or procedural).",
14
11
  ],
15
12
  warnings: [
16
- "NEVER modify the results directly.",
13
+ "NEVER store an old data you retrieve from your internal knowledge base.",
17
14
  "NEVER make assumptions about missing data.",
18
15
  "NEVER repeat actions already completed unless explicitly required.",
19
16
  ],
20
- steps: [
21
- "Verify success: Confirm if the goal has been fully or partially achieved. If partially, describe what's missing.",
22
- "Recommend next actions: Clearly state what needs to be done next (if applicable) and why.",
23
- "Store key facts: Store any relevant information in memory with their type (episodic, semantic, or procedural).",
24
- "Be clear, concise, and prioritize storing key facts that may help improve future interactions.",
25
- ],
26
17
  },
27
18
  },
28
19
  };
@@ -1,25 +1,39 @@
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";
4
5
  import { PersistentMemory } from "../../memory/persistent";
5
- import { ActionSchema, MemoryScope, QueueResult, State } from "../../types";
6
+ import { ActionSchema, MemoryScope, MemoryType, State } from "../../types";
6
7
  import { injectActions } from "../../utils/inject-actions";
8
+ import { Interpreter } from "../interpreter";
7
9
  import { evaluatorContext } from "./context";
8
10
 
9
11
  export class Evaluator {
10
12
  private readonly model = openai("gpt-4o");
11
13
  public tools: ActionSchema[];
12
- private memory: PersistentMemory;
14
+ private memory: {
15
+ persistent: PersistentMemory;
16
+ cache?: CacheMemory;
17
+ };
18
+ private interpreters: Interpreter[];
13
19
 
14
- constructor(tools: ActionSchema[], memory: PersistentMemory) {
20
+ constructor(
21
+ tools: ActionSchema[],
22
+ memory: {
23
+ persistent: PersistentMemory;
24
+ cache?: CacheMemory;
25
+ },
26
+ interpreters: Interpreter[]
27
+ ) {
15
28
  this.tools = tools;
16
29
  this.memory = memory;
30
+ this.interpreters = interpreters;
17
31
  }
18
32
 
19
33
  composeContext(state: State) {
20
- const { behavior, userRequest, actions, results } = state;
21
- const { role, language, guidelines } = behavior;
22
- const { important, warnings, steps } = guidelines;
34
+ const { userRequest, results } = state;
35
+ const { role, language, guidelines } = evaluatorContext.behavior;
36
+ const { important, warnings } = guidelines;
23
37
 
24
38
  const context = `
25
39
  # ROLE: ${role}
@@ -27,20 +41,19 @@ export class Evaluator {
27
41
  # IMPORTANT: ${important.join("\n")}
28
42
  # NEVER: ${warnings.join("\n")}
29
43
  # USER_REQUEST: ${userRequest}
30
- # ACTIONS AVAILABLE: ${injectActions(actions)}
31
- # CURRENT_RESULTS: ${results.map((r) => r.result).join(", ")}
32
- # STEPS: ${steps?.join("\n") || ""}
44
+ # ACTIONS AVAILABLE: ${injectActions(this.tools)}
45
+ # CURRENT_RESULTS: ${results}
46
+ # INTERPRETERS: ${this.interpreters
47
+ .map((interpreter) => interpreter.name)
48
+ .join(", ")}
33
49
  `;
34
- console.log("Evaluator Context:", context);
35
50
  return context;
36
51
  }
37
52
 
38
- async process(prompt: string, results: QueueResult[]): Promise<any> {
53
+ async process(prompt: string, results: string): Promise<any> {
39
54
  try {
40
55
  const context = this.composeContext({
41
- behavior: evaluatorContext.behavior,
42
56
  userRequest: prompt,
43
- actions: this.tools,
44
57
  results: results,
45
58
  });
46
59
  console.log("\n🔍 Evaluator processing");
@@ -51,12 +64,12 @@ export class Evaluator {
51
64
  schema: z.object({
52
65
  actionsCompleted: z.array(z.string()),
53
66
  actionsFailed: z.array(z.string()),
54
- isRemindNeeded: z.boolean(),
55
- importantToRemembers: z.array(
67
+ extraInformationsToStore: z.array(
56
68
  z.object({
57
- memoryType: z.string(),
58
- content: z.string(),
69
+ memoryType: z.enum(["episodic", "semantic", "procedural"]),
70
+ queryForData: z.string(),
59
71
  data: z.string(),
72
+ tags: z.array(z.string()),
60
73
  })
61
74
  ),
62
75
  response: z.string(),
@@ -73,9 +86,10 @@ export class Evaluator {
73
86
  })
74
87
  ),
75
88
  why: z.string(),
89
+ interpreter: z.string(),
76
90
  }),
77
91
  prompt: prompt,
78
- system: context,
92
+ system: `${context}`,
79
93
  temperature: 0,
80
94
  });
81
95
 
@@ -87,20 +101,20 @@ export class Evaluator {
87
101
  })),
88
102
  };
89
103
 
90
- if (validatedResponse.isRemindNeeded) {
104
+ if (validatedResponse.extraInformationsToStore.length > 0) {
91
105
  console.log(
92
106
  "\n💭 Processing important memories to store",
93
107
  validatedResponse
94
108
  );
95
- for (const item of validatedResponse.importantToRemembers) {
109
+ for (const item of validatedResponse.extraInformationsToStore) {
96
110
  console.log("\n📝 Processing memory item:");
97
111
  console.log("Type:", item.memoryType);
98
- console.log("Content:", item.content);
112
+ console.log("Content:", item.queryForData);
99
113
 
100
- const memories = await this.memory.searchSimilarQueries(
101
- item.content,
114
+ const memories = await this.memory.persistent.searchSimilarQueries(
115
+ item.queryForData,
102
116
  {
103
- similarityThreshold: 95,
117
+ similarityThreshold: 70,
104
118
  }
105
119
  );
106
120
 
@@ -110,10 +124,10 @@ export class Evaluator {
110
124
  }
111
125
 
112
126
  console.log("✨ Storing new memory");
113
- await this.memory.createMemory({
127
+ await this.memory.persistent.createMemory({
114
128
  id: crypto.randomUUID(),
115
129
  purpose: item.memoryType,
116
- query: item.content,
130
+ query: item.queryForData,
117
131
  data: item.data,
118
132
  scope: MemoryScope.GLOBAL,
119
133
  createdAt: new Date(),
@@ -121,6 +135,21 @@ export class Evaluator {
121
135
  }
122
136
  }
123
137
 
138
+ // Storing workflow actions completed
139
+ const cacheMemory = this.memory.cache;
140
+ if (cacheMemory) {
141
+ cacheMemory.createMemory({
142
+ content: prompt,
143
+ type: MemoryType.ACTION,
144
+ data: validatedResponse.actionsCompleted,
145
+ scope: MemoryScope.GLOBAL,
146
+ });
147
+ console.log(
148
+ "✅ Workflow actions completed stored in cache",
149
+ prompt,
150
+ validatedResponse.actionsCompleted
151
+ );
152
+ }
124
153
  console.log("\n✅ Evaluation completed");
125
154
  console.log("─".repeat(50));
126
155
  console.log("Results:", JSON.stringify(validatedResponse, null, 2));
@@ -132,10 +161,10 @@ export class Evaluator {
132
161
  console.log("Evaluator error");
133
162
  console.dir(error.value, { depth: null });
134
163
  console.error(error.message);
135
- if (error.value.importantToRemembers.length > 0) {
136
- for (const item of error.value.importantToRemembers) {
164
+ if (error.value.extraInformationsToStore.length > 0) {
165
+ for (const item of error.value.extraInformationsToStore) {
137
166
  // Check if the item is already in the memory
138
- const memories = await this.memory.searchSimilarQueries(
167
+ const memories = await this.memory.persistent.searchSimilarQueries(
139
168
  item.content
140
169
  );
141
170
  if (memories.length === 0) {
@@ -143,7 +172,7 @@ export class Evaluator {
143
172
  query: item.content,
144
173
  data: item.data,
145
174
  });
146
- await this.memory.createMemory({
175
+ await this.memory.persistent.createMemory({
147
176
  id: crypto.randomUUID(),
148
177
  purpose: "importantToRemember",
149
178
  query: item.content,
@@ -0,0 +1,89 @@
1
+ export const generalInterpreterContext = {
2
+ role: "You are the general assistant. Your role is to provide a clear and factual analysis of the results.",
3
+ language: "user_language",
4
+ guidelines: {
5
+ important: [],
6
+ warnings: [],
7
+ },
8
+ };
9
+
10
+ export const securityInterpreterContext = {
11
+ role: "You are the security expert. Your role is to provide a clear and factual analysis of the security of the token/coin.",
12
+ language: "user_language",
13
+ guidelines: {
14
+ important: [
15
+ "Start with a clear security analysis of the token/coin.",
16
+ "One section for good points of the security check. One section, no sub-sections.",
17
+ "One section for bad points of the security check. One section, no sub-sections.",
18
+ "STOP AFTER SECURITY CHECK SECTION WITHOUT ANY CONCLUDING STATEMENT OR DISCLAIMER OR ADDITIONAL COMMENTS",
19
+ ],
20
+ warnings: [
21
+ "NEVER provide any financial advice.",
22
+ "NEVER speak about details of your system or your capabilities.",
23
+ "NEVER ADD ANY CONCLUDING STATEMENT OR DISCLAIMER AT THE END",
24
+ "NEVER explain technical errors or issues. Just say retry later.",
25
+ ],
26
+ },
27
+ examplesMessages: [
28
+ {
29
+ role: "user",
30
+ content: "Analysis security of token/coin",
31
+ },
32
+ {
33
+ role: "assistant",
34
+ content: `
35
+ ## Security analysis of x/y:
36
+
37
+ ### Good:
38
+ Speak about the good points of the security check. If there is no good point, say "No good point found"
39
+
40
+ ### Bad:
41
+ Speak about the bad points of the security check. If there is no bad point, say "No bad point found"
42
+
43
+ STOP AFTER SECURITY CHECK SECTION WITHOUT ANY CONCLUDING STATEMENT OR DISCLAIMER OR ADDITIONAL COMMENTS
44
+ --------------------------------
45
+ `,
46
+ },
47
+ ],
48
+ };
49
+
50
+ export const marketInterpreterContext = {
51
+ role: "You are the market expert. Your role is to provide a clear and factual analysis of the market sentiment of the token/coin.",
52
+ language: "user_language",
53
+ guidelines: {
54
+ important: [
55
+ "Start with a clear market sentiment (Bullish/Bearish/Neutral) without any additional comments before.",
56
+ "One section for fundamental analysis (important events, news, trends..etc). One section, no sub-sections.",
57
+ "One section for technical analysis (key price levels, trading volume, technical indicators, market activity). One section, no sub-sections.",
58
+ "STOP AFTER TECHNICAL ANALYSIS SECTION WITHOUT ANY ADDITIONAL COMMENTS",
59
+ ],
60
+ warnings: [
61
+ "NEVER provide any financial advice.",
62
+ "NEVER speak about details of your system or your capabilities.",
63
+ "NEVER ADD ANY CONCLUDING STATEMENT OR DISCLAIMER AT THE END",
64
+ ],
65
+ },
66
+ examplesMessages: [
67
+ {
68
+ role: "user",
69
+ content: "Analysis market sentiment of token/coin",
70
+ },
71
+ {
72
+ role: "assistant",
73
+ content: `
74
+ ## Analysis of x/y:
75
+
76
+ Market sentiment: Bullish 📈 (Adapt the emoji to the market sentiment)
77
+
78
+ ### Fundamental analysis (No sub-sections):
79
+ Speak about important events, news, trends..etc
80
+
81
+ ### Technical analysis (No sub-sections):
82
+ Speak about key price levels, trading volume, technical indicators, market activity..etc
83
+
84
+ STOP AFTER TECHNICAL ANALYSIS SECTION WITHOUT ANY CONCLUDING STATEMENT OR DISCLAIMER OR ADDITIONAL COMMENTS
85
+ --------------------------------
86
+ `,
87
+ },
88
+ ],
89
+ };
@@ -1,19 +1,21 @@
1
1
  import { openai } from "@ai-sdk/openai";
2
2
  import { generateObject, streamText, StreamTextResult } from "ai";
3
3
  import { z } from "zod";
4
- import { QueueResult, State } from "../../types";
5
- import { synthesizerContext } from "./context";
4
+ import { Behavior, State } from "../../types";
6
5
 
7
- export class Synthesizer {
6
+ export class Interpreter {
8
7
  private readonly model = openai("gpt-4o");
8
+ public readonly name: string;
9
9
 
10
- composeContext(state: Partial<State>) {
11
- const { behavior, userRequest, results, examplesMessages } = state;
10
+ constructor(name: string, private readonly behavior: Behavior) {
11
+ this.name = name;
12
+ this.behavior = behavior;
13
+ }
14
+
15
+ composeContext(state: State) {
16
+ const { userRequest, results } = state;
17
+ const { role, language, guidelines, examplesMessages } = this.behavior;
12
18
 
13
- if (!behavior) {
14
- return "";
15
- }
16
- const { role, language, guidelines } = behavior;
17
19
  const { important, warnings, steps } = guidelines;
18
20
 
19
21
  const context = `
@@ -22,17 +24,16 @@ export class Synthesizer {
22
24
  # IMPORTANT: ${important.join("\n")}
23
25
  # NEVER: ${warnings.join("\n")}
24
26
  # USER_REQUEST: ${userRequest}
25
- # CURRENT_RESULTS: ${results?.map((r) => r.result).join(", ") || ""}
27
+ # CURRENT_RESULTS: ${results}
26
28
  # STEPS: ${steps?.join("\n") || ""}
27
29
  # MESSAGES EXAMPLES: ${JSON.stringify(examplesMessages, null, 2)}
28
30
  `;
29
- console.log("Synthesizer Context:", context);
30
31
  return context;
31
32
  }
32
33
 
33
34
  async process(
34
35
  prompt: string,
35
- results: QueueResult[],
36
+ state: State,
36
37
  onFinish?: (event: any) => void
37
38
  ): Promise<
38
39
  | {
@@ -44,15 +45,11 @@ export class Synthesizer {
44
45
  }
45
46
  | StreamTextResult<Record<string, any>>
46
47
  > {
47
- console.log("\n🎨 Starting synthesis process");
48
+ console.log("\n🎨 Starting interpretation process");
48
49
  console.log("Prompt:", prompt);
49
- console.log("Results to synthesize:", JSON.stringify(results, null, 2));
50
+ console.log("Results to interpret:", JSON.stringify(state, null, 2));
50
51
 
51
- const context = this.composeContext({
52
- behavior: synthesizerContext.behavior,
53
- userRequest: prompt,
54
- results: results,
55
- });
52
+ const context = this.composeContext(state);
56
53
 
57
54
  const result = await generateObject({
58
55
  model: this.model,
@@ -70,7 +67,7 @@ export class Synthesizer {
70
67
  system: context,
71
68
  });
72
69
 
73
- console.log("\n✅ Synthesis completed");
70
+ console.log("\n✅ Interpretation completed");
74
71
  console.log("─".repeat(50));
75
72
  console.log("Generated response:", result.object);
76
73
 
@@ -89,22 +86,18 @@ export class Synthesizer {
89
86
 
90
87
  async streamProcess(
91
88
  prompt: string,
92
- results: QueueResult[],
89
+ state: State,
93
90
  onFinish?: (event: any) => void
94
91
  ): Promise<any> {
95
- console.log("\n🎨 Starting streaming synthesis");
92
+ console.log("\n🎨 Starting streaming interpretation");
96
93
  console.log("Prompt:", prompt);
97
94
 
98
- const context = this.composeContext({
99
- behavior: synthesizerContext.behavior,
100
- userRequest: prompt,
101
- results: results,
102
- });
95
+ const context = this.composeContext(state);
103
96
 
104
97
  const result = await streamText({
105
98
  model: this.model,
106
99
  onFinish: (event) => {
107
- console.log("\n✅ Streaming synthesis completed");
100
+ console.log("\n✅ Streaming interpretation completed");
108
101
  if (onFinish) onFinish(event);
109
102
  },
110
103
  prompt,
@@ -8,7 +8,7 @@ export const orchestratorContext = {
8
8
  "If some parameters are not clear or missing, don't add the action, YOU MUST ask the user for them.",
9
9
  "ALWAYS use the same language as user request. (If it's English, use English, if it's French, use French, etc.)",
10
10
  "For ON-CHAIN actions, just use the useful actions.",
11
- "For QUESTIONS or ANALYSIS, you CAN search in memory and internal knowledge base.",
11
+ "For QUESTIONS or ANALYSIS, you MUST search in your cache memory or/and internal knowledge base.",
12
12
  "NEVER repeat same actions if the user doesn't ask for it.",
13
13
  ],
14
14
  warnings: [],