@ai.ntellect/core 0.5.0 → 0.6.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.
Files changed (131) hide show
  1. package/.mocharc.json +1 -1
  2. package/README.md +311 -272
  3. package/create-llm-to-select-multiple-graph copy.ts +243 -0
  4. package/create-llm-to-select-multiple-graph.ts +148 -0
  5. package/dist/graph/controller.js +63 -0
  6. package/dist/graph/engine.js +563 -0
  7. package/dist/index.js +6 -6
  8. package/dist/memory/adapters/meilisearch/index.js +249 -0
  9. package/dist/memory/adapters/redis/index.js +96 -0
  10. package/dist/memory/index.js +9 -0
  11. package/dist/services/agenda.js +115 -0
  12. package/dist/services/embedding.js +40 -0
  13. package/dist/services/queue.js +99 -103
  14. package/dist/test/graph/controller.test.js +170 -0
  15. package/dist/test/graph/engine.test.js +465 -0
  16. package/dist/test/memory/adapters/meilisearch.test.js +250 -0
  17. package/dist/test/memory/adapters/redis.test.js +143 -0
  18. package/dist/test/memory/base.test.js +209 -0
  19. package/dist/test/services/agenda.test.js +230 -0
  20. package/dist/test/services/queue.test.js +258 -0
  21. package/dist/types/index.js +2 -0
  22. package/dist/utils/generate-object.js +32 -11
  23. package/dist/utils/inject-actions.js +2 -2
  24. package/dist/utils/queue-item-transformer.js +2 -2
  25. package/dist/utils/state-manager.js +20 -0
  26. package/graph/controller.ts +64 -0
  27. package/graph/engine.ts +790 -0
  28. package/index copy.ts +81 -0
  29. package/index.ts +7 -7
  30. package/interfaces/index.ts +119 -0
  31. package/memory/adapters/meilisearch/index.ts +286 -0
  32. package/memory/adapters/redis/index.ts +103 -0
  33. package/memory/index.ts +22 -0
  34. package/package.json +7 -2
  35. package/services/agenda.ts +48 -43
  36. package/services/embedding.ts +26 -0
  37. package/services/queue.ts +2 -29
  38. package/test/.env.test +4 -0
  39. package/test/graph/controller.test.ts +186 -0
  40. package/test/graph/engine.test.ts +546 -0
  41. package/test/memory/adapters/meilisearch.test.ts +297 -0
  42. package/test/memory/adapters/redis.test.ts +160 -0
  43. package/test/memory/base.test.ts +229 -0
  44. package/test/services/agenda.test.ts +280 -0
  45. package/test/services/queue.test.ts +286 -44
  46. package/tsconfig.json +10 -10
  47. package/types/index.ts +278 -0
  48. package/utils/queue-item-transformer.ts +8 -11
  49. package/utils/setup-graphs.ts +45 -0
  50. package/utils/stringifiy-zod-schema.ts +45 -0
  51. package/.nvmrc +0 -1
  52. package/README.FR.md +0 -916
  53. package/agent/index.ts +0 -151
  54. package/agent/workflow/conditions.ts +0 -16
  55. package/agent/workflow/handlers/interpreter.handler.ts +0 -48
  56. package/agent/workflow/handlers/memory.handler.ts +0 -106
  57. package/agent/workflow/handlers/orchestrator.handler.ts +0 -23
  58. package/agent/workflow/handlers/queue.handler.ts +0 -34
  59. package/agent/workflow/handlers/scheduler.handler.ts +0 -61
  60. package/agent/workflow/index.ts +0 -62
  61. package/dist/agent/index.d.ts +0 -38
  62. package/dist/agent/index.js +0 -143
  63. package/dist/agent/tools/get-rss.d.ts +0 -16
  64. package/dist/agent/tools/get-rss.js +0 -62
  65. package/dist/bull.d.ts +0 -1
  66. package/dist/bull.js +0 -9
  67. package/dist/examples/index.d.ts +0 -2
  68. package/dist/examples/index.js +0 -89
  69. package/dist/index.d.ts +0 -7
  70. package/dist/llm/interpreter/context.d.ts +0 -15
  71. package/dist/llm/interpreter/context.js +0 -89
  72. package/dist/llm/interpreter/index.d.ts +0 -21
  73. package/dist/llm/interpreter/index.js +0 -87
  74. package/dist/llm/memory-manager/context.d.ts +0 -2
  75. package/dist/llm/memory-manager/context.js +0 -22
  76. package/dist/llm/memory-manager/index.d.ts +0 -17
  77. package/dist/llm/memory-manager/index.js +0 -107
  78. package/dist/llm/orchestrator/context.d.ts +0 -2
  79. package/dist/llm/orchestrator/context.js +0 -23
  80. package/dist/llm/orchestrator/index.d.ts +0 -44
  81. package/dist/llm/orchestrator/index.js +0 -139
  82. package/dist/llm/orchestrator/types.d.ts +0 -12
  83. package/dist/memory/cache.d.ts +0 -22
  84. package/dist/memory/cache.js +0 -165
  85. package/dist/memory/persistent.d.ts +0 -57
  86. package/dist/memory/persistent.js +0 -189
  87. package/dist/services/queue.d.ts +0 -13
  88. package/dist/services/redis-cache.d.ts +0 -37
  89. package/dist/services/redis-cache.js +0 -93
  90. package/dist/services/scheduler.d.ts +0 -40
  91. package/dist/services/scheduler.js +0 -99
  92. package/dist/services/telegram-monitor.d.ts +0 -0
  93. package/dist/services/telegram-monitor.js +0 -118
  94. package/dist/t.d.ts +0 -46
  95. package/dist/t.js +0 -102
  96. package/dist/test.d.ts +0 -0
  97. package/dist/test.js +0 -438
  98. package/dist/types.d.ts +0 -258
  99. package/dist/types.js +0 -22
  100. package/dist/utils/generate-object.d.ts +0 -12
  101. package/dist/utils/header-builder.d.ts +0 -11
  102. package/dist/utils/inject-actions.d.ts +0 -2
  103. package/dist/utils/queue-item-transformer.d.ts +0 -7
  104. package/dist/utils/sanitize-results.d.ts +0 -17
  105. package/dist/utils/schema-generator.d.ts +0 -16
  106. package/examples/actions/get-rss.ts +0 -71
  107. package/examples/index.ts +0 -98
  108. package/index.html +0 -42
  109. package/llm/dynamic-condition/example.ts +0 -36
  110. package/llm/dynamic-condition/index.ts +0 -108
  111. package/llm/interpreter/context.ts +0 -94
  112. package/llm/interpreter/index.ts +0 -140
  113. package/llm/memory-manager/context.ts +0 -19
  114. package/llm/memory-manager/index.ts +0 -115
  115. package/llm/orchestrator/context.ts +0 -19
  116. package/llm/orchestrator/index.ts +0 -192
  117. package/llm/orchestrator/types.ts +0 -14
  118. package/memory/cache.ts +0 -221
  119. package/memory/persistent.ts +0 -265
  120. package/script.js +0 -167
  121. package/services/cache.ts +0 -298
  122. package/services/telegram-monitor.ts +0 -138
  123. package/services/workflow.ts +0 -491
  124. package/t.py +0 -79
  125. package/t.ts +0 -25
  126. package/test/llm/orchestrator.test.ts +0 -47
  127. package/test/llm/synthesizer.test.ts +0 -31
  128. package/types.ts +0 -367
  129. package/utils/schema-generator.ts +0 -73
  130. package/utils/state-manager.ts +0 -25
  131. /package/dist/{llm/orchestrator/types.js → interfaces/index.js} +0 -0
package/README.FR.md DELETED
@@ -1,916 +0,0 @@
1
- # AI.ntellect Core Framework
2
-
3
- ## Vue d'ensemble
4
-
5
- Ce framework est conçu pour exécuter des workflows complexes à l'aide d'une orchestration avancée, de la gestion de mémoire et d'une intelligence exploitable. Il intègre des outils, des interpréteurs et des systèmes de mémoire pour :
6
-
7
- - Analyser les entrées utilisateur dans leur contexte.
8
- - Exécuter des workflows prédéfinis et des actions dynamiques.
9
- - Gérer efficacement la mémoire à court et à long terme.
10
- - Permettre une intégration fluide avec des API et outils externes.
11
-
12
- ---
13
-
14
- ## Table des matières
15
-
16
- 1. [Composants d'architecture](#composants-darchitecture)
17
-
18
- - [Workflow](#workflow)
19
- - [Orchestrateur](#orchestrateur)
20
- - [Gestionnaire de file d'attente](#gestionnaire-de-file-dattente)
21
- - [Interpréteur](#interpréteur)
22
- - [Système de mémoire](#système-de-mémoire)
23
- - [Listeners](#listeners)
24
- - [Schedulers](#schedulers)
25
-
26
- 2. [Définir et exécuter des actions](#définir-et-exécuter-des-actions)
27
- 3. [Gestion de l'état et récursivité](#gestion-de-letat-et-recursivité)
28
- 4. [Installation et configuration](#installation-et-configuration)
29
- 5. [Exemple d'utilisation](#exemple-dutilisation)
30
- 6. [Travaux en cours (WIP)](#travaux-en-cours-wip)
31
-
32
- ---
33
-
34
- ## Composants d'architecture
35
-
36
- import { configDotenv } from "dotenv";
37
- import EventEmitter from "events";
38
- import {
39
- GraphDefinition,
40
- mergeState,
41
- Node,
42
- Persistence,
43
- RealTimeNotifier,
44
- SharedState,
45
- } from "../types";
46
- import { WorkflowExecutor } from "./workflow-executor";
47
-
48
- configDotenv();
49
-
50
- /\*\*
51
-
52
- - Represents a directed graph structure capable of executing nodes in sequence or parallel.
53
- - The graph can handle state management, event emissions, and conditional execution paths.
54
- -
55
- - @template T - The type of data stored in the graph's context
56
- _/
57
- export class Workflow<T> {
58
- /\*\* Stores global context data accessible to all nodes _/
59
- public globalContext: Map<string, any>;
60
-
61
- /\*_ Event emitter for handling graph-wide events _/
62
- private eventEmitter: EventEmitter;
63
-
64
- /\*_ Map of all nodes in the graph _/
65
- public nodes: Map<string, Node<T>>;
66
-
67
- /\*_ Set of nodes that have been executed _/
68
- public executedNodes: Set<string>;
69
-
70
- /\*_ Name identifier for the graph _/
71
- public name: string;
72
-
73
- /\*_ Optional persistence layer for saving graph state _/
74
- private persistence: Persistence<T> | null;
75
-
76
- /\*_ Optional notifier for real-time updates _/
77
- private notifier: RealTimeNotifier | null;
78
-
79
- /\*\*
80
-
81
- - Creates a new Graph instance.
82
- -
83
- - @param {GraphDefinition<T>} [definition] - Initial graph structure and configuration
84
- - @param {Object} [config] - Additional configuration options
85
- - @param {boolean} [config.autoDetectCycles] - Whether to check for cycles during initialization
86
- - @throws {Error} If cycles are detected when autoDetectCycles is true
87
- \*/
88
- constructor(
89
- definition?: GraphDefinition<T>,
90
- config?: { autoDetectCycles?: boolean }
91
- ) {
92
- this.name = definition?.name || "anonymous";
93
- this.eventEmitter = new EventEmitter();
94
- this.globalContext = new Map();
95
- this.nodes = new Map();
96
- this.executedNodes = new Set();
97
- this.persistence = null;
98
- this.notifier = null;
99
-
100
-
101
- if (definition) {
102
- this.loadFromDefinition(definition);
103
- }
104
-
105
- if (config?.autoDetectCycles && this.checkForCycles()) {
106
- throw new Error("Cycle detected in the graph");
107
- }
108
-
109
- }
110
-
111
- /\*\*
112
-
113
- - Adds a value to the global context.
114
- - @param {string} key - The key to store the value under
115
- - @param {any} value - The value to store
116
- \*/
117
- addToContext(key: string, value: any): void {
118
- this.globalContext.set(key, value);
119
- }
120
-
121
- /\*\*
122
-
123
- - Retrieves a value from the global context.
124
- - @param {string} key - The key to retrieve
125
- - @returns {any} The stored value, or undefined if not found
126
- \*/
127
- getContext(key: string): any {
128
- return this.globalContext.get(key);
129
- }
130
-
131
- /\*\*
132
-
133
- - Removes a value from the global context.
134
- - @param {string} key - The key to remove
135
- \*/
136
- removeFromContext(key: string): void {
137
- this.globalContext.delete(key);
138
- }
139
-
140
- /\*\*
141
-
142
- - Sets the persistence layer for the graph.
143
- - @param {Persistence<T>} persistence - The persistence implementation
144
- \*/
145
- setPersistence(persistence: Persistence<T>): void {
146
- this.persistence = persistence;
147
- }
148
-
149
- /\*\*
150
-
151
- - Sets the real-time notifier for the graph.
152
- - @param {RealTimeNotifier} notifier - The notifier implementation
153
- \*/
154
- setNotifier(notifier: RealTimeNotifier): void {
155
- this.notifier = notifier;
156
- }
157
-
158
- /\*\*
159
-
160
- - Loads a graph structure from a definition object.
161
- - @private
162
- - @param {GraphDefinition<T>} definition - The graph definition
163
- \*/
164
- private loadFromDefinition(definition: GraphDefinition<T>): void {
165
- Object.entries(definition.nodes).forEach(([_, nodeConfig]) => {
166
- this.addNode(nodeConfig, {
167
- condition: nodeConfig.condition,
168
- next: nodeConfig.next,
169
- });
170
- });
171
- }
172
-
173
- /\*\*
174
-
175
- - Recursively checks if a node is part of a cycle.
176
- - @private
177
- - @param {string} nodeName - The name of the node to check
178
- - @param {Set<string>} visited - Set of visited nodes
179
- - @param {Set<string>} recStack - Set of nodes in the current recursion stack
180
- - @returns {boolean} True if a cycle is detected, false otherwise
181
- \*/
182
- private isCyclic(
183
- nodeName: string,
184
- visited: Set<string>,
185
- recStack: Set<string>
186
- ): boolean {
187
- if (!visited.has(nodeName)) {
188
- visited.add(nodeName);
189
- recStack.add(nodeName);
190
-
191
- const currentNode = this.nodes.get(nodeName);
192
- if (currentNode?.next) {
193
- for (const nextNode of currentNode.next) {
194
- if (
195
- !visited.has(nextNode) &&
196
- this.isCyclic(nextNode, visited, recStack)
197
- ) {
198
- return true;
199
- } else if (recStack.has(nextNode)) {
200
- return true;
201
- }
202
- }
203
- }
204
-
205
- }
206
- recStack.delete(nodeName);
207
- return false;
208
- }
209
-
210
- /\*\*
211
-
212
- - Checks if the graph contains any cycles.
213
- - @returns {boolean} True if cycles are detected, false otherwise
214
- \*/
215
- public checkForCycles(): boolean {
216
- const visited = new Set<string>();
217
- const recStack = new Set<string>();
218
-
219
-
220
- for (const nodeName of this.nodes.keys()) {
221
- if (this.isCyclic(nodeName, visited, recStack)) {
222
- return true;
223
- }
224
- }
225
- return false;
226
-
227
- }
228
-
229
- /\*\*
230
-
231
- - Adds a new node to the graph.
232
- - @param {Node<T>} node - The node to add
233
- - @param {Object} options - Node configuration options
234
- - @param {Function} [options.condition] - Condition function for node execution
235
- - @param {string[]} [options.next] - Array of next node names
236
- - @param {string[]} [options.events] - Array of event names to listen for
237
- \*/
238
- addNode(
239
- node: Node<T>,
240
- {
241
- condition,
242
- next,
243
- events,
244
- }: {
245
- condition?: (state: SharedState<T>) => boolean;
246
- next?: string[];
247
- events?: string[];
248
- }
249
- ): void {
250
- node.next = next;
251
- node.condition = condition;
252
-
253
-
254
- if (events) {
255
- events.forEach((event) => {
256
- this.eventEmitter.on(event, async (data) => {
257
- console.log(`Event "${event}" received by node "${node.name}"`);
258
- const state = data.state || {};
259
- await this.execute(state, node.name);
260
- });
261
- });
262
- }
263
-
264
- this.nodes.set(node.name, node);
265
-
266
- }
267
-
268
- /\*\*
269
-
270
- - Emits an event to the graph's event emitter.
271
- - @param {string} eventName - Name of the event to emit
272
- - @param {any} data - Data to pass with the event
273
- \*/
274
- public emit(eventName: string, data: any): void {
275
- console.log(`Event "${eventName}" emitted with data:`, data);
276
- this.eventEmitter.emit(eventName, data);
277
- }
278
-
279
- /\*\*
280
-
281
- - Adds a subgraph as a node in the current graph.
282
- - @param {Graph<T>} subGraph - The subgraph to add
283
- - @param {string} entryNode - The entry node name in the subgraph
284
- - @param {string} name - The name for the subgraph node
285
- \*/
286
- addSubGraph(subGraph: Workflow<T>, entryNode: string, name: string): void {
287
- const subGraphNode: Node<T> = {
288
- name,
289
- execute: async (state) => {
290
- console.log(`Executing subgraph: ${name}`);
291
- await subGraph.execute(state, entryNode);
292
- return state;
293
- },
294
- };
295
- this.nodes.set(name, subGraphNode);
296
- }
297
-
298
- /\*\*
299
-
300
- - Executes the graph starting from a specific node.
301
- - @param {SharedState<T>} state - The initial state
302
- - @param {string} startNode - The name of the starting node
303
- - @param {Function} [onStream] - Callback for streaming state updates
304
- - @param {Function} [onError] - Callback for handling errors
305
- \*/
306
- async execute(
307
- state: SharedState<T>,
308
- startNode: string,
309
- onStream?: (state: SharedState<T>) => void,
310
- onError?: (error: Error, nodeName: string, state: SharedState<T>) => void
311
- ): Promise<void> {
312
- let currentNodeName = startNode;
313
-
314
-
315
- while (currentNodeName) {
316
- this.executedNodes.add(currentNodeName);
317
-
318
- const currentNode = this.nodes.get(currentNodeName);
319
- if (!currentNode) throw new Error(`Node ${currentNodeName} not found.`);
320
-
321
- if (currentNode.condition && !currentNode.condition(state)) {
322
- console.log(
323
- `Condition for node "${currentNodeName}" not met. Ending Graph.`
324
- );
325
- break;
326
- }
327
-
328
- try {
329
- if (this.notifier) {
330
- this.notifier.notify("nodeExecutionStarted", {
331
- graph: this.name,
332
- node: currentNodeName,
333
- });
334
- }
335
-
336
- console.log(`Executing node: ${currentNodeName}`);
337
- const newState = await currentNode.execute(state);
338
- Object.assign(state, mergeState(state, newState));
339
-
340
- if (onStream) onStream(state);
341
-
342
- if (this.persistence) {
343
- await this.persistence.saveState(this.name, state, currentNodeName);
344
- }
345
-
346
- if (this.notifier) {
347
- await this.notifier.notify("nodeExecutionCompleted", {
348
- graph: this.name,
349
- node: currentNodeName,
350
- state,
351
- });
352
- }
353
- } catch (error) {
354
- console.error(`Error in node ${currentNodeName}:`, error);
355
- if (onError) onError(error as Error, currentNodeName, state);
356
- if (this.notifier) {
357
- this.notifier.notify("nodeExecutionFailed", {
358
- graph: this.name,
359
- node: currentNodeName,
360
- state,
361
- error,
362
- });
363
- }
364
- break;
365
- }
366
-
367
- const nextNodes = currentNode.next || [];
368
- if (nextNodes.length > 1) {
369
- await Promise.all(
370
- nextNodes.map((nextNode) =>
371
- this.execute(state, nextNode, onStream, onError)
372
- )
373
- );
374
- break;
375
- } else {
376
- currentNodeName = nextNodes[0] || "";
377
- }
378
- }
379
-
380
- console.log(`Graph completed for node: ${startNode}`);
381
-
382
- }
383
-
384
- /\*\*
385
-
386
- - Executes multiple nodes in parallel with a concurrency limit.
387
- - @param {SharedState<T>} state - The shared state
388
- - @param {string[]} nodeNames - Array of node names to execute
389
- - @param {number} [concurrencyLimit=5] - Maximum number of concurrent executions
390
- - @param {Function} [onStream] - Callback for streaming state updates
391
- - @param {Function} [onError] - Callback for handling errors
392
- \*/
393
- async executeParallel(
394
- state: SharedState<T>,
395
- nodeNames: string[],
396
- concurrencyLimit: number = 5,
397
- onStream?: (state: SharedState<T>) => void,
398
- onError?: (error: Error, nodeName: string, state: SharedState<T>) => void
399
- ): Promise<void> {
400
- console.log(`Executing nodes in parallel: ${nodeNames.join(", ")}`);
401
-
402
-
403
- const executeWithLimit = async (nodeName: string) => {
404
- await this.execute(state, nodeName, onStream, onError);
405
- };
406
-
407
- const chunks = [];
408
- for (let i = 0; i < nodeNames.length; i += concurrencyLimit) {
409
- chunks.push(nodeNames.slice(i, i + concurrencyLimit));
410
- }
411
-
412
- for (const chunk of chunks) {
413
- await Promise.all(chunk.map(executeWithLimit));
414
- }
415
-
416
- }
417
-
418
- /\*\*
419
-
420
- - Updates the graph structure with a new definition.
421
- - @param {GraphDefinition<T>} definition - The new graph definition
422
- \*/
423
- updateGraph(definition: GraphDefinition<T>): void {
424
- Object.entries(definition.nodes).forEach(([_, nodeConfig]) => {
425
- if (this.nodes.has(nodeConfig.name)) {
426
- const existingNode = this.nodes.get(nodeConfig.name)!;
427
- existingNode.next = nodeConfig.next || existingNode.next;
428
- existingNode.condition = nodeConfig.condition || existingNode.condition;
429
- } else {
430
- this.addNode(nodeConfig, {
431
- condition: nodeConfig.condition,
432
- next: nodeConfig.next,
433
- });
434
- }
435
- });
436
- }
437
-
438
- /\*\*
439
-
440
- - Replace the graph with a new definition.
441
- - @param {GraphDefinition<T>} definition - The new graph definition
442
- \*/
443
- replaceGraph(definition: GraphDefinition<T>): void {
444
- this.nodes.clear();
445
- this.loadFromDefinition(definition);
446
- }
447
-
448
- /\*\*
449
-
450
- - Generates a visual representation of the graph using Mermaid diagram syntax.
451
- - The diagram shows all nodes and their connections, with special highlighting for:
452
- - - Entry nodes (green)
453
- - - Event nodes (yellow)
454
- - - Conditional nodes (orange)
455
- -
456
- - @param {string} [title] - Optional title for the diagram
457
- - @returns {string} Mermaid diagram syntax representing the graph
458
- \*/
459
- generateMermaidDiagram(title?: string): string {
460
- const lines: string[] = ["graph TD"];
461
-
462
-
463
- if (title) {
464
- lines.push(` subgraph ${title}`);
465
- }
466
-
467
- // Add nodes with styling
468
- this.nodes.forEach((node, nodeName) => {
469
- const hasEvents = node.events && node.events.length > 0;
470
- const hasCondition = !!node.condition;
471
-
472
- // Style nodes based on their properties
473
- let style = "";
474
- if (hasEvents) {
475
- style = "style " + nodeName + " fill:#FFD700,stroke:#DAA520"; // Yellow for event nodes
476
- } else if (hasCondition) {
477
- style = "style " + nodeName + " fill:#FFA500,stroke:#FF8C00"; // Orange for conditional nodes
478
- }
479
-
480
- // Add node definition
481
- lines.push(` ${nodeName}[${nodeName}]`);
482
- if (style) {
483
- lines.push(` ${style}`);
484
- }
485
- });
486
-
487
- // Add connections
488
- this.nodes.forEach((node, nodeName) => {
489
- if (node.next) {
490
- node.next.forEach((nextNode) => {
491
- let connectionStyle = "";
492
- if (node.condition) {
493
- connectionStyle = "---|condition|"; // Add label for conditional connections
494
- } else {
495
- connectionStyle = "-->"; // Normal connection
496
- }
497
- lines.push(` ${nodeName} ${connectionStyle} ${nextNode}`);
498
- });
499
- }
500
-
501
- // Add event connections if any
502
- if (node.events && node.events.length > 0) {
503
- node.events.forEach((event) => {
504
- const eventNodeId = `${event}_event`;
505
- lines.push(` ${eventNodeId}((${event})):::event`);
506
- lines.push(` ${eventNodeId} -.->|trigger| ${nodeName}`);
507
- });
508
- // Add style class for event nodes
509
- lines.push(" classDef event fill:#FFD700,stroke:#DAA520");
510
- }
511
- });
512
-
513
- if (title) {
514
- lines.push(" end");
515
- }
516
-
517
- return lines.join("\n");
518
-
519
- }
520
-
521
- /\*\*
522
-
523
- - Renders the graph visualization using Mermaid syntax.
524
- - This method can be used to visualize the graph structure in supported environments.
525
- -
526
- - @param {string} [title] - Optional title for the visualization
527
- \*/
528
- visualize(title?: string): void {
529
- const diagram = this.generateMermaidDiagram(title);
530
- console.log(
531
- "To visualize this graph, use a Mermaid-compatible renderer with this syntax:"
532
- );
533
- console.log("\n`mermaid");
534
- console.log(diagram);
535
- console.log("`\n");
536
- }
537
-
538
- exportGraphToJson<T>(graph: GraphDefinition<T>): string {
539
- const result = {
540
- graphName: graph.name,
541
- entryNode: graph.entryNode,
542
- nodes: Object.entries(graph.nodes).reduce((acc, [key, node]) => {
543
- acc[key] = {
544
- name: node.name,
545
- description: node.description || "No description provided",
546
- execute: node.execute.name,
547
- condition: node.condition ? node.condition.toString() : "None",
548
- next: node.next || [],
549
- };
550
- return acc;
551
- }, {} as Record<string, any>),
552
- };
553
- return JSON.stringify(result, null, 2);
554
- }
555
- }
556
- // Création des workflows
557
- const workflowA = new Workflow({
558
- name: "WorkflowA",
559
- entryNode: "node1",
560
- nodes: {
561
- node1: {
562
- name: "node1",
563
- execute: async (state: any) => {
564
- console.log("WorkflowA node1 executed", state);
565
- return Promise.resolve({});
566
- },
567
- },
568
- node2: {
569
- name: "node2",
570
- execute: async (state: any) => {
571
- console.log("WorkflowA node2 executed", state);
572
- return Promise.resolve({});
573
- },
574
- events: ["event1"],
575
- },
576
- },
577
- });
578
-
579
- const workflowB = new Workflow({
580
- name: "WorkflowB",
581
- entryNode: "node1",
582
- nodes: {
583
- node1: {
584
- name: "node1",
585
- execute: async (state: any) => {
586
- console.log("WorkflowB node1 executed", state);
587
- state.exampleData = "test2";
588
- return Promise.resolve({});
589
- },
590
- },
591
- },
592
- });
593
-
594
- // Initialisation du gestionnaire d'exécution
595
- const executor = new WorkflowExecutor();
596
-
597
- workflowA.emit("event1", { exampleData: "test" });
598
-
599
- // Ajout des workflows
600
- executor.addWorkflow("WorkflowA", workflowA);
601
- executor.addWorkflow("WorkflowB", workflowB);
602
-
603
- // Exécution des workflows en parallèle
604
- executor.executeWorkflowsInParallel(
605
- ["WorkflowA", "WorkflowB"],
606
- {
607
- exampleData: "test",
608
- },
609
- 2
610
- );
611
-
612
- ---
613
-
614
- ### Orchestrateur
615
-
616
- L'**orchestrateur** dirige les workflows en analysant les entrées utilisateur et en planifiant les actions. Il interagit avec les outils, les systèmes de mémoire et les interpréteurs pour garantir une exécution logique.
617
-
618
- **Caractéristiques clés :**
619
-
620
- - Sélection dynamique des actions en fonction du contexte.
621
- - Gestion des interactions mémoire pour les opérations RAG et CAG.
622
- - Gestion des workflows multi-étapes avec affinage itératif.
623
-
624
- ---
625
-
626
- ### Gestionnaire de file d'attente
627
-
628
- Le **gestionnaire de file d'attente** est chargé d'organiser et d'exécuter les actions dans le bon ordre, qu'elles soient séquentielles ou parallèles. Il agit comme le mécanisme central pour gérer les workflows, en s'assurant que chaque action est correctement mise en file d'attente, validée et exécutée.
629
-
630
- **Responsabilités principales :**
631
-
632
- 1. **Mise en file d'attente des actions :**
633
-
634
- - Les actions sont ajoutées à une file pour exécution, individuellement ou en lot.
635
- - Prise en charge des journaux pour le débogage et la traçabilité.
636
-
637
- 2. **Traitement des actions :**
638
-
639
- - Exécute les actions en maintenant le bon ordre.
640
- - Respecte les dépendances entre les actions.
641
- - Gère les erreurs ou confirmations via des rappels.
642
-
643
- 3. **Gestion des confirmations :**
644
- - Prend en charge les invites de confirmation pour les actions critiques.
645
- - S'appuie sur des rappels pour décider de poursuivre des actions spécifiques.
646
-
647
- **Exemple :**
648
-
649
- ```typescript
650
- import { ActionQueueManager } from "@ai-ntellect/core";
651
- import { actions, callbacks } from "@ai-ntellect/core/examples";
652
-
653
- const queueManager = new ActionQueueManager(actions, callbacks);
654
- queueManager.addToQueue([{ name: "fetch-data", parameters: [...] }]);
655
- const results = await queueManager.processQueue();
656
- console.log("Résultats :", results);
657
- ```
658
-
659
- ---
660
-
661
- ### Interpréteur
662
-
663
- L'**interpréteur** se spécialise dans l'analyse des résultats et la génération d'informations spécifiques à un domaine. Chaque interpréteur est adapté à un cas d'utilisation particulier et utilise sa propre configuration de caractère.
664
-
665
- **Exemples :**
666
-
667
- 1. **MarketInterpreter** : Analyse des données financières de marché.
668
- 2. **SecurityInterpreter** : Vérification de la sécurité.
669
- 3. **GeneralInterpreter** : Traitement des demandes générales.
670
-
671
- #### Workflow d'interprétation
672
-
673
- 1. Construit un contexte avec l'état actuel, y compris les résultats et les demandes utilisateur.
674
- 2. Utilise le modèle de langage pour générer des informations exploitables.
675
- 3. Fournit des réponses détaillées pour l'utilisateur final.
676
-
677
- ---
678
-
679
- ### Système de mémoire
680
-
681
- L'architecture mémoire combine une mémoire à court terme et une mémoire à long terme pour fournir un traitement contextuel.
682
-
683
- #### Types de mémoire
684
-
685
- 1. **Mémoire cache (Redis) :**
686
- - Stocke des données temporaires pour un accès rapide.
687
- - Exemples : Actions récentes, données de session.
688
- 2. **Mémoire persistante (Meilisearch) :**
689
- - Stocke des données à long terme comme les interactions historiques et les connaissances.
690
- - Permet des recherches sémantiques et des récupérations basées sur des vecteurs.
691
-
692
- ---
693
-
694
- ### Listeners
695
-
696
- Les **listeners** permettent de se connecter à des événements externes via WebSocket. Ils écoutent les mises à jour en temps réel et déclenchent des actions ou des callbacks spécifiques en réponse aux événements.
697
-
698
- **Caractéristiques principales :**
699
-
700
- - Connexion à des WebSockets pour écouter les événements.
701
- - Gestion des abonnements avec des messages personnalisés.
702
- - Déclenchement de callbacks pour traiter les données reçues.
703
-
704
- **Exemple d'utilisation :**
705
-
706
- ```typescript
707
- agent.addListener(
708
- "listener-id",
709
- "wss://example.com/socket",
710
- () => JSON.stringify({ action: "subscribe" }),
711
- async (data) => {
712
- console.log("Data reçue :", data);
713
- }
714
- );
715
- ```
716
-
717
- ---
718
-
719
- ### Schedulers
720
-
721
- Les **schedulers** permettent de planifier des tâches ou actions pour une exécution ultérieure. Ils utilisent des expressions cron pour définir les intervalles de planification.
722
-
723
- **Caractéristiques principales :**
724
-
725
- - Planification basée sur des expressions cron.
726
- - Support des tâches récurrentes et non récurrentes.
727
- - Gestion et annulation des tâches planifiées.
728
-
729
- **Exemple d'utilisation :**
730
-
731
- ```typescript
732
- const scheduler = new TaskScheduler(agentRuntime, redisCache);
733
-
734
- const taskId = await scheduler.scheduleRequest({
735
- originalRequest: "Analyse de marché",
736
- cronExpression: "0 9 * * *", // Tous les jours à 9h
737
- });
738
-
739
- console.log(`Tâche planifiée avec ID : ${taskId}`);
740
-
741
- // Annuler la tâche si nécessaire
742
- scheduler.cancelScheduledRequest(taskId);
743
- ```
744
-
745
- ---
746
-
747
- ## Définir et exécuter des actions
748
-
749
- ### Qu'est-ce qu'une action ?
750
-
751
- Les actions sont les tâches fondamentales exécutées par le framework. Chaque action comprend :
752
-
753
- - Un nom et une description uniques.
754
- - Des paramètres d'entrée validés à l'aide de schémas.
755
- - Une logique d'exécution encapsulée dans la méthode `execute`.
756
-
757
- ### Exemple d'action
758
-
759
- ```typescript
760
- import { z } from "zod";
761
- import { parseEther } from "ethers";
762
-
763
- export const prepareTransaction = {
764
- name: "prepare-transaction",
765
- description: "Prépare un transfert de token pour approbation utilisateur.",
766
- parameters: z.object({
767
- walletAddress: z.string(),
768
- amount: z.string(),
769
- networkId: z.string(),
770
- }),
771
- execute: async ({ walletAddress, amount, networkId }) => {
772
- return {
773
- to: walletAddress,
774
- value: parseEther(amount).toString(),
775
- network: networkId,
776
- };
777
- },
778
- };
779
- ```
780
-
781
- ---
782
-
783
- ## Gestion de l'état et récursivité
784
-
785
- L'agent gère l'état et les workflows récursifs pour s'assurer que les actions sont exécutées de manière ordonnée et jusqu'à leur achèvement, tout en respectant un maximum d'itérations pour éviter les boucles infinies.
786
-
787
- ### Gestion de l'état
788
-
789
- L'état (`State`) contient :
790
-
791
- - `currentContext` : Contexte actuel de la requête utilisateur.
792
- - `previousActions` : Liste des actions exécutées précédemment.
793
-
794
- Lorsqu'une action est terminée, l'état est mis à jour pour inclure :
795
-
796
- - Les résultats des actions précédentes.
797
- - Le contexte restant à traiter.
798
-
799
- ### Récursivité contrôlée
800
-
801
- Pour éviter les boucles infinies, le système limite le nombre d'itérations via la configuration `maxIterations`.
802
-
803
- **Fonctionnement :**
804
-
805
- 1. **Initialisation :** À chaque itération, l'agent :
806
-
807
- - Exécute les actions dans la file d'attente.
808
- - Met à jour l'état avec les nouveaux résultats.
809
-
810
- 2. **Validation des limites :**
811
-
812
- - Si le nombre d'itérations dépasse `maxIterations`, le traitement est interrompu avec un message "Max iterations reached".
813
-
814
- 3. **Récursivité :**
815
- - Si des actions restent à exécuter, l'agent appelle récursivement la méthode `process` avec le nouvel état.
816
-
817
- **Exemple de gestion d'état et récursivité :**
818
-
819
- ```typescript
820
- const updatedNextState: State = {
821
- ...state,
822
- currentContext: state.currentContext,
823
- previousActions: [...(state.previousActions || []), ...(results || [])],
824
- };
825
-
826
- if (countIterations < this.config.maxIterations) {
827
- return this.process(updatedNextState);
828
- } else {
829
- console.log("Max iterations reached");
830
- response.shouldContinue = false;
831
- }
832
- ```
833
-
834
- ---
835
-
836
- ## Installation et configuration
837
-
838
- ### Installer les dépendances
839
-
840
- ```bash
841
- npm install
842
- ```
843
-
844
- ### Configurer les services externes
845
-
846
- #### Redis (Mémoire cache)
847
-
848
- ```bash
849
- docker run --name redis -d -p 6379:6379 redis
850
- ```
851
-
852
- #### Meilisearch (Mémoire persistante)
853
-
854
- ```bash
855
- curl -L https://install.meilisearch.com | sh
856
- ./meilisearch --master-key="VOTRE_CLÉ_MAÎTRE"
857
- ```
858
-
859
- ---
860
-
861
- ## Exemple d'utilisation
862
-
863
- ### Initialiser l'agent
864
-
865
- ```typescript
866
- import { deepseek } from "@ai-ntellect/core";
867
- import { Agent } from "@ai-ntellect/core";
868
- import { checkHoneypot, fetchMarkPrice } from "@ai-ntellect/core/actions";
869
- import {
870
- generalInterpreterCharacter,
871
- marketInterpreterCharacter,
872
- securityInterpreterCharacter,
873
- } from "@ai-ntellect/core/interpreter/context";
874
-
875
- const model = deepseek("deepseek-reasoner");
876
-
877
- const agent = new Agent({
878
- orchestrator: {
879
- model,
880
- tools: [checkHoneypot, fetchMarkPrice],
881
- },
882
- interpreters: [
883
- new Interpreter({
884
- name: "security",
885
- model,
886
- character: securityInterpreterCharacter,
887
- }),
888
- new Interpreter({
889
- name: "market",
890
- model,
891
- character: marketInterpreterCharacter,
892
- }),
893
- new Interpreter({
894
- name: "general",
895
- model,
896
- character: generalInterpreterCharacter,
897
- }),
898
- ],
899
- memoryManager: {
900
- model,
901
- },
902
- maxIterations: 3,
903
- });
904
- ```
905
-
906
- ### Traiter une demande
907
-
908
- ```typescript
909
- const state = {
910
- currentContext: "Analyse des tendances de marché XRP/USD",
911
- previousActions: [],
912
- };
913
-
914
- const result = await agent.process(state);
915
- console.log("Résultat :", result);
916
- ```