@ai.ntellect/core 0.6.0 → 0.6.2

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 (37) hide show
  1. package/create-llm-to-select-multiple-graph copy.ts +243 -0
  2. package/create-llm-to-select-multiple-graph.ts +148 -0
  3. package/dist/create-llm-to-select-multiple-graph copy.js +201 -0
  4. package/dist/create-llm-to-select-multiple-graph.js +142 -0
  5. package/dist/graph/controller.js +6 -6
  6. package/dist/graph/engine.js +198 -135
  7. package/dist/index copy.js +76 -0
  8. package/dist/utils/setup-graphs.js +28 -0
  9. package/dist/utils/stringifiy-zod-schema.js +41 -0
  10. package/graph/controller.ts +11 -9
  11. package/graph/engine.ts +244 -166
  12. package/index copy.ts +81 -0
  13. package/index.ts +1 -1
  14. package/package.json +1 -1
  15. package/test/graph/engine.test.ts +27 -44
  16. package/tsconfig.json +1 -1
  17. package/types/index.ts +11 -3
  18. package/utils/setup-graphs.ts +45 -0
  19. package/utils/stringifiy-zod-schema.ts +45 -0
  20. package/dist/test/graph/controller.test.js +0 -170
  21. package/dist/test/graph/engine.test.js +0 -465
  22. package/dist/test/memory/adapters/meilisearch.test.js +0 -250
  23. package/dist/test/memory/adapters/redis.test.js +0 -143
  24. package/dist/test/memory/base.test.js +0 -209
  25. package/dist/test/services/agenda.test.js +0 -230
  26. package/dist/test/services/queue.test.js +0 -258
  27. package/dist/utils/schema-generator.js +0 -46
  28. package/dist/utils/state-manager.js +0 -20
  29. package/utils/generate-object.js +0 -111
  30. package/utils/header-builder.js +0 -34
  31. package/utils/inject-actions.js +0 -16
  32. package/utils/queue-item-transformer.js +0 -24
  33. package/utils/sanitize-results.js +0 -60
  34. package/utils/schema-generator.js +0 -46
  35. package/utils/schema-generator.ts +0 -73
  36. package/utils/state-manager.js +0 -20
  37. package/utils/state-manager.ts +0 -30
@@ -13,24 +13,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.GraphEngine = void 0;
16
- const dotenv_1 = require("dotenv");
17
16
  const events_1 = __importDefault(require("events"));
18
17
  const zod_1 = require("zod");
19
- (0, dotenv_1.configDotenv)();
20
18
  /**
21
- * Represents a directed worflow structure capable of executing nodes in sequence or parallel.
22
- * The worflow can handle state management, event emissions, and conditional execution paths.
19
+ * Représente un workflow dirigé capable d’exécuter des noeuds en séquence ou en parallèle.
23
20
  *
24
- * @template T - The type of data stored in the worflow's context
21
+ * @template T - Le type de données stockées dans le contexte du workflow
25
22
  */
26
23
  class GraphEngine {
27
24
  /**
28
- * Creates a new Graph instance.
25
+ * Crée une nouvelle instance de GraphEngine.
29
26
  *
30
- * @param {GraphDefinition<T>} [definition] - Initial worflow structure and configuration
31
- * @param {Object} [config] - Additional configuration options
32
- * @param {boolean} [config.autoDetectCycles] - Whether to check for cycles during initialization
33
- * @throws {Error} If cycles are detected when autoDetectCycles is true
27
+ * @param {GraphDefinition<T>} [definition] - La définition initiale du workflow
28
+ * @param {GraphOptions<T>} [options] - Options de configuration
34
29
  */
35
30
  constructor(definition, options) {
36
31
  this.name = (definition === null || definition === void 0 ? void 0 : definition.name) || "anonymous";
@@ -41,74 +36,69 @@ class GraphEngine {
41
36
  this.persistence = null;
42
37
  this.notifier = null;
43
38
  this.schema = options === null || options === void 0 ? void 0 : options.schema;
44
- this.currentState = { context: {} };
39
+ this.currentState = {};
45
40
  if (definition) {
46
41
  this.loadFromDefinition(definition);
47
42
  }
48
43
  if ((options === null || options === void 0 ? void 0 : options.autoDetectCycles) && this.checkForCycles()) {
49
- throw new Error("Cycle detected in the workflow");
44
+ throw new Error("Cycle détecté dans le workflow");
50
45
  }
51
46
  if (options === null || options === void 0 ? void 0 : options.initialState) {
52
47
  this.setState(options.initialState);
53
48
  }
54
49
  }
55
50
  /**
56
- * Adds a value to the global context.
57
- * @param {string} key - The key to store the value under
58
- * @param {any} value - The value to store
51
+ * Ajoute un élément au contexte global.
52
+ * @param {string} key - La clé
53
+ * @param {any} value - La valeur
59
54
  */
60
55
  addToContext(key, value) {
61
56
  this.globalContext.set(key, value);
62
57
  }
63
58
  /**
64
- * Retrieves a value from the global context.
65
- * @param {string} key - The key to retrieve
66
- * @returns {any} The stored value, or undefined if not found
59
+ * Récupère un élément du contexte global.
60
+ * @param {string} key - La clé
67
61
  */
68
62
  getContext(key) {
69
63
  return this.globalContext.get(key);
70
64
  }
71
65
  /**
72
- * Removes a value from the global context.
73
- * @param {string} key - The key to remove
66
+ * Supprime un élément du contexte global.
67
+ * @param {string} key - La clé
74
68
  */
75
69
  removeFromContext(key) {
76
70
  this.globalContext.delete(key);
77
71
  }
78
72
  /**
79
- * Sets the persistence layer for the worflow.
80
- * @param {Persistence<T>} persistence - The persistence implementation
73
+ * Définit la couche de persistance.
74
+ * @param {Persistence<T>} persistence
81
75
  */
82
76
  setPersistence(persistence) {
83
77
  this.persistence = persistence;
84
78
  }
85
79
  /**
86
- * Sets the real-time notifier for the worflow.
87
- * @param {RealTimeNotifier} notifier - The notifier implementation
80
+ * Définit le notifier en temps réel.
81
+ * @param {RealTimeNotifier} notifier
88
82
  */
89
83
  setNotifier(notifier) {
90
84
  this.notifier = notifier;
91
85
  }
92
86
  /**
93
- * Loads a worflow structure from a definition object.
87
+ * Charge un workflow à partir d'une définition.
94
88
  * @private
95
- * @param {GraphDefinition<T>} definition - The worflow definition
89
+ * @param {GraphDefinition<T>} definition
96
90
  */
97
91
  loadFromDefinition(definition) {
98
92
  Object.entries(definition.nodes).forEach(([_, nodeConfig]) => {
99
- this.addNode(nodeConfig, {
100
- condition: nodeConfig.condition,
101
- relationships: nodeConfig.relationships,
102
- });
93
+ this.addNode(nodeConfig);
103
94
  });
104
95
  }
105
96
  /**
106
- * Recursively checks if a node is part of a cycle.
107
- * @private
108
- * @param {string} nodeName - The name of the node to check
109
- * @param {Set<string>} visited - Set of visited nodes
110
- * @param {Set<string>} recStack - Set of nodes in the current recursion stack
111
- * @returns {boolean} True if a cycle is detected, false otherwise
97
+ * Vérifie récursivement s’il existe un cycle dans le workflow.
98
+ * @param {string} nodeName
99
+ * @param {Set<string>} visited
100
+ * @param {Set<string>} recStack
101
+ * @returns {boolean}
112
102
  */
113
103
  isCyclic(nodeName, visited, recStack) {
114
104
  if (!visited.has(nodeName)) {
@@ -132,8 +122,8 @@ class GraphEngine {
132
122
  return false;
133
123
  }
134
124
  /**
135
- * Checks if the worflow contains any cycles.
136
- * @returns {boolean} True if cycles are detected, false otherwise
125
+ * Vérifie si le workflow contient des cycles.
126
+ * @returns {boolean}
137
127
  */
138
128
  checkForCycles() {
139
129
  const visited = new Set();
@@ -146,18 +136,18 @@ class GraphEngine {
146
136
  return false;
147
137
  }
148
138
  /**
149
- * Adds a new node to the worflow.
150
- * @param {Node<T>} node - The node to add
151
- * @param {Object} options - Node configuration options
152
- * @param {Function} [options.condition] - Condition function for node execution
153
- * @param {string[]} [options.relations] - Array of relations node names
154
- * @param {string[]} [options.events] - Array of event names to listen for
139
+ * Ajoute un nouveau nœud au workflow.
140
+ * @param {Node<T>} node
155
141
  */
156
- addNode(node, { condition, relationships, events, }) {
157
- node.relationships = relationships;
158
- node.condition = condition;
159
- if (events) {
160
- events.forEach((event) => {
142
+ addNode(node) {
143
+ if (node.relationships) {
144
+ node.relationships.forEach((relationship) => {
145
+ var _a, _b;
146
+ (_b = (_a = this.nodes.get(relationship.name)) === null || _a === void 0 ? void 0 : _a.relationships) === null || _b === void 0 ? void 0 : _b.push(relationship);
147
+ });
148
+ }
149
+ if (node.events) {
150
+ node.events.forEach((event) => {
161
151
  this.eventEmitter.on(event, (data) => __awaiter(this, void 0, void 0, function* () {
162
152
  const state = data.state || {};
163
153
  yield this.execute(state, node.name);
@@ -167,18 +157,18 @@ class GraphEngine {
167
157
  this.nodes.set(node.name, node);
168
158
  }
169
159
  /**
170
- * Emits an event to the worflow's event emitter.
171
- * @param {string} eventName - Name of the event to emit
172
- * @param {any} data - Data to pass with the event
160
+ * Émet un événement sur l'event emitter du workflow.
161
+ * @param {string} eventName
162
+ * @param {any} data
173
163
  */
174
164
  emit(eventName, data) {
175
165
  this.eventEmitter.emit(eventName, data);
176
166
  }
177
167
  /**
178
- * Adds a subworflow as a node in the current worflow.
179
- * @param {Graph<T>} subGraph - The subworflow to add
180
- * @param {string} entryNode - The entry node name in the subworflow
181
- * @param {string} name - The name for the subworflow node
168
+ * Ajoute un sous-graph (GraphEngine) comme un nœud dans le workflow courant.
169
+ * @param {GraphEngine<T>} subGraph
170
+ * @param {string} entryNode - Le nom du nœud de démarrage dans le sous-graph
171
+ * @param {string} name - Le nom symbolique à donner au sous-graph
182
172
  */
183
173
  addSubGraph(subGraph, entryNode, name) {
184
174
  const subGraphNode = {
@@ -191,22 +181,23 @@ class GraphEngine {
191
181
  this.nodes.set(name, subGraphNode);
192
182
  }
193
183
  /**
194
- * Executes the worflow starting from a specific node.
195
- * @param {SharedState<T>} state - The initial state
196
- * @param {string} startNode - The name of the starting node
197
- * @param {Function} [onStream] - Callback for streaming state updates
198
- * @param {Function} [onError] - Callback for handling errors
184
+ * Exécute le workflow à partir d’un nœud donné.
185
+ * @param {SharedState<T>} state
186
+ * @param {string} startNode
187
+ * @param {(state: SharedState<T>) => void} [onStream] - Callback sur l’évolution de l’état
188
+ * @param {(error: Error, nodeName: string, state: SharedState<T>) => void} [onError] - Callback sur erreur
199
189
  */
200
190
  execute(state, startNode, onStream, onError) {
201
191
  return __awaiter(this, void 0, void 0, function* () {
202
192
  var _a, _b;
203
193
  try {
194
+ // Valide l'état initial via le schéma global (si défini)
204
195
  if (this.schema) {
205
196
  try {
206
- this.schema.parse(state.context);
197
+ this.schema.parse(state);
207
198
  }
208
199
  catch (error) {
209
- const validationError = new Error(`Initial state validation failed: ${error instanceof Error ? error.message : error}`);
200
+ const validationError = new Error(`Échec de la validation de l'état initial: ${error instanceof Error ? error.message : error}`);
210
201
  if (onError)
211
202
  onError(validationError, startNode, state);
212
203
  throw validationError;
@@ -217,13 +208,16 @@ class GraphEngine {
217
208
  while (currentNodeName) {
218
209
  this.executedNodes.add(currentNodeName);
219
210
  const currentNode = this.nodes.get(currentNodeName);
220
- if (!currentNode)
221
- throw new Error(`Node ${currentNodeName} not found.`);
211
+ if (!currentNode) {
212
+ throw new Error(`Nœud ${currentNodeName} introuvable.`);
213
+ }
214
+ // Vérification de condition (si présente)
222
215
  if (currentNode.condition &&
223
216
  !currentNode.condition(this.currentState)) {
224
217
  break;
225
218
  }
226
219
  try {
220
+ // Notifier : début d'exécution du nœud
227
221
  if (this.notifier) {
228
222
  this.notifier.notify("nodeExecutionStarted", {
229
223
  workflow: this.name,
@@ -235,11 +229,13 @@ class GraphEngine {
235
229
  if (newState) {
236
230
  this.setState(newState);
237
231
  if (onStream)
238
- onStream(this.currentState);
232
+ onStream(this);
239
233
  }
234
+ // Sauvegarde via la persistence (optionnel)
240
235
  if (this.persistence) {
241
236
  yield this.persistence.saveState(this.name, this.currentState, currentNodeName);
242
237
  }
238
+ // Notifier : fin d'exécution du nœud
243
239
  if (this.notifier) {
244
240
  yield this.notifier.notify("nodeExecutionCompleted", {
245
241
  workflow: this.name,
@@ -249,8 +245,9 @@ class GraphEngine {
249
245
  }
250
246
  }
251
247
  catch (error) {
252
- if (onError)
248
+ if (onError) {
253
249
  onError(error, currentNodeName, this.currentState);
250
+ }
254
251
  if (this.notifier) {
255
252
  this.notifier.notify("nodeExecutionFailed", {
256
253
  workflow: this.name,
@@ -261,12 +258,16 @@ class GraphEngine {
261
258
  }
262
259
  break;
263
260
  }
261
+ // Gestion des relations (branchements)
264
262
  const relationsNodes = currentNode.relationships || [];
265
263
  if (relationsNodes.length > 1) {
264
+ // Exécution parallèle des branches
266
265
  yield Promise.all(relationsNodes.map((relation) => this.execute(this.currentState, relation.name, onStream, onError)));
266
+ // Après exécution en parallèle, on arrête la boucle
267
267
  break;
268
268
  }
269
269
  else {
270
+ // Cas normal : un seul chemin
270
271
  currentNodeName = ((_b = relationsNodes[0]) === null || _b === void 0 ? void 0 : _b.name) || "";
271
272
  }
272
273
  }
@@ -281,12 +282,10 @@ class GraphEngine {
281
282
  });
282
283
  }
283
284
  /**
284
- * Executes multiple nodes in parallel with a concurrency limit.
285
- * @param {SharedState<T>} state - The shared state
286
- * @param {string[]} nodeNames - Array of node names to execute
287
- * @param {number} [concurrencyLimit=5] - Maximum number of concurrent executions
288
- * @param {Function} [onStream] - Callback for streaming state updates
289
- * @param {Function} [onError] - Callback for handling errors
285
+ * Exécute plusieurs nœuds en parallèle au sein du même workflow, avec une limite de concurrence.
286
+ * @param {SharedState<T>} state
287
+ * @param {string[]} nodeNames
288
+ * @param {number} [concurrencyLimit=5]
290
289
  */
291
290
  executeParallel(state_1, nodeNames_1) {
292
291
  return __awaiter(this, arguments, void 0, function* (state, nodeNames, concurrencyLimit = 5, onStream, onError) {
@@ -303,8 +302,8 @@ class GraphEngine {
303
302
  });
304
303
  }
305
304
  /**
306
- * Updates the worflow structure with a new definition.
307
- * @param {GraphDefinition<T>} definition - The new worflow definition
305
+ * Met à jour le workflow avec une nouvelle définition (mise à jour des nœuds existants ou ajout de nouveaux).
306
+ * @param {GraphDefinition<T>} definition
308
307
  */
309
308
  updateGraph(definition) {
310
309
  Object.entries(definition.nodes).forEach(([_, nodeConfig]) => {
@@ -313,78 +312,69 @@ class GraphEngine {
313
312
  existingNode.relationships =
314
313
  nodeConfig.relationships || existingNode.relationships;
315
314
  existingNode.condition = nodeConfig.condition || existingNode.condition;
315
+ existingNode.events = nodeConfig.events || existingNode.events;
316
316
  }
317
317
  else {
318
- this.addNode(nodeConfig, {
319
- condition: nodeConfig.condition,
320
- relationships: nodeConfig.relationships,
321
- });
318
+ this.addNode(nodeConfig);
322
319
  }
323
320
  });
324
321
  }
325
322
  /**
326
- * Replace the worflow with a new definition.
327
- * @param {GraphDefinition<T>} definition - The new worflow definition
323
+ * Remplace complètement le workflow par une nouvelle définition.
324
+ * @param {GraphDefinition<T>} definition
328
325
  */
329
326
  replaceGraph(definition) {
330
327
  this.nodes.clear();
331
328
  this.loadFromDefinition(definition);
332
329
  }
333
330
  /**
334
- * Generates a visual representation of the worflow using Mermaid diagram syntax.
335
- * The diagram shows all nodes and their connections, with special highlighting for:
336
- * - Entry nodes (green)
337
- * - Event nodes (yellow)
338
- * - Conditional nodes (orange)
339
- *
340
- * @param {string} [title] - Optional title for the diagram
341
- * @returns {string} Mermaid diagram syntax representing the worflow
331
+ * Génère un diagramme Mermaid pour visualiser le workflow.
332
+ * @param {string} [title]
333
+ * @returns {string}
342
334
  */
343
335
  generateMermaidDiagram(title) {
344
336
  const lines = ["flowchart TD"];
345
337
  if (title) {
346
338
  lines.push(` subgraph ${title}`);
347
339
  }
348
- // Add nodes with styling
340
+ // Ajout des nœuds
349
341
  this.nodes.forEach((node, nodeName) => {
350
342
  const hasEvents = node.events && node.events.length > 0;
351
343
  const hasCondition = !!node.condition;
352
- // Style nodes based on their properties
344
+ // Style selon les propriétés
353
345
  let style = "";
354
346
  if (hasEvents) {
355
- style = "style " + nodeName + " fill:#FFD700,stroke:#DAA520"; // Yellow for event nodes
347
+ style = "style " + nodeName + " fill:#FFD700,stroke:#DAA520"; // Jaune pour event
356
348
  }
357
349
  else if (hasCondition) {
358
- style = "style " + nodeName + " fill:#FFA500,stroke:#FF8C00"; // Orange for conditional nodes
350
+ style = "style " + nodeName + " fill:#FFA500,stroke:#FF8C00"; // Orange pour condition
359
351
  }
360
- // Add node definition
361
352
  lines.push(` ${nodeName}[${nodeName}]`);
362
353
  if (style) {
363
354
  lines.push(` ${style}`);
364
355
  }
365
356
  });
366
- // Add connections
357
+ // Ajout des connexions
367
358
  this.nodes.forEach((node, nodeName) => {
368
359
  if (node.relationships) {
369
360
  node.relationships.forEach((relationsNode) => {
370
361
  let connectionStyle = "";
371
362
  if (node.condition) {
372
- connectionStyle = "---|condition|"; // Add label for conditional connections
363
+ connectionStyle = "---|condition|";
373
364
  }
374
365
  else {
375
- connectionStyle = "-->"; // Normal connection
366
+ connectionStyle = "-->";
376
367
  }
377
368
  lines.push(` ${nodeName} ${connectionStyle} ${relationsNode}`);
378
369
  });
379
370
  }
380
- // Add event connections if any
371
+ // Gestion des events
381
372
  if (node.events && node.events.length > 0) {
382
373
  node.events.forEach((event) => {
383
374
  const eventNodeId = `${event}_event`;
384
375
  lines.push(` ${eventNodeId}((${event})):::event`);
385
376
  lines.push(` ${eventNodeId} -.->|trigger| ${nodeName}`);
386
377
  });
387
- // Add style class for event nodes
388
378
  lines.push(" classDef event fill:#FFD700,stroke:#DAA520");
389
379
  }
390
380
  });
@@ -394,23 +384,26 @@ class GraphEngine {
394
384
  return lines.join("\n");
395
385
  }
396
386
  /**
397
- * Renders the worflow visualization using Mermaid syntax.
398
- * This method can be used to visualize the worflow structure in supported environments.
399
- *
400
- * @param {string} [title] - Optional title for the visualization
387
+ * Affiche le diagramme Mermaid dans la console.
388
+ * @param {string} [title]
401
389
  */
402
390
  visualize(title) {
403
391
  const diagram = this.generateMermaidDiagram(title);
404
- console.log("To visualize this worflow, use a Mermaid-compatible renderer with this syntax:");
392
+ console.log("Pour visualiser ce workflow, utilisez un rendu compatible Mermaid avec la syntaxe suivante :");
405
393
  console.log("\n```mermaid");
406
394
  console.log(diagram);
407
395
  console.log("```\n");
408
396
  }
409
- exportGraphToJson(worflow) {
397
+ /**
398
+ * Exporte la définition du workflow au format JSON (pour debug ou documentation).
399
+ * @param {GraphDefinition<T>} workflow
400
+ * @returns {string} JSON string
401
+ */
402
+ exportGraphToJson(workflow) {
410
403
  const result = {
411
- worflowName: worflow.name,
412
- entryNode: worflow.entryNode,
413
- nodes: Object.entries(worflow.nodes).reduce((acc, [key, node]) => {
404
+ workflowName: workflow.name,
405
+ entryNode: workflow.entryNode,
406
+ nodes: Object.entries(workflow.nodes).reduce((acc, [key, node]) => {
414
407
  acc[key] = {
415
408
  name: node.name,
416
409
  description: node.description || "No description provided",
@@ -424,15 +417,14 @@ class GraphEngine {
424
417
  return JSON.stringify(result, null, 2);
425
418
  }
426
419
  /**
427
- * Generates a visual representation of the workflow schema.
428
- * Displays the structure of the data expected for each node.
429
- *
430
- * @returns {string} A formatted string describing the workflow schema
420
+ * Génère une représentation textuelle (console) du schéma du workflow.
421
+ * @returns {string}
431
422
  */
432
423
  visualizeSchema() {
433
424
  const output = [];
434
425
  output.push(`📋 Graph: ${this.name}`);
435
426
  output.push("=".repeat(50));
427
+ // Schéma global
436
428
  if (this.schema) {
437
429
  output.push("🔷 Global Schema:");
438
430
  output.push("-".repeat(30));
@@ -446,20 +438,25 @@ class GraphEngine {
446
438
  }
447
439
  output.push("");
448
440
  }
441
+ // Détails des nœuds
449
442
  output.push("🔷 Nodes:");
450
443
  output.push("-".repeat(30));
451
444
  this.nodes.forEach((node, nodeName) => {
452
445
  output.push(`\n📍 Node: ${nodeName}`);
453
446
  output.push(`Description: ${node.description || "No description provided"}`);
454
447
  if (node.relationships && node.relationships.length > 0) {
455
- output.push(`Next nodes: ${node.relationships.join(", ")}`);
448
+ const rels = node.relationships.map((r) => r.name).join(", ");
449
+ output.push(`Next nodes: ${rels}`);
456
450
  }
457
451
  output.push("");
458
452
  });
459
453
  return output.join("\n");
460
454
  }
461
455
  /**
462
- * Recursively describes a Zod type.
456
+ * Décrit récursivement un type Zod pour l'affichage.
457
+ * @param {z.ZodType} type
458
+ * @param {number} indent
459
+ * @returns {string}
463
460
  */
464
461
  describeZodType(type, indent = 0) {
465
462
  const padding = " ".repeat(indent);
@@ -505,29 +502,29 @@ class GraphEngine {
505
502
  return type.constructor.name.replace("Zod", "") || "unknown";
506
503
  }
507
504
  /**
508
- * Updates the state of a node.
509
- * @param {SharedState<T>} state - The current state
510
- * @param {Partial<T>} updates - The updates to apply
511
- * @returns {SharedState<T>} The updated state
505
+ * Met à jour le contexte du workflow pour un nœud, en renvoyant un nouvel état.
506
+ * @param {SharedState<T>} state
507
+ * @param {Partial<T>} updates
508
+ * @returns {SharedState<T>}
512
509
  */
513
510
  updateNodeState(state, updates) {
514
- return Object.assign(Object.assign({}, state), { context: Object.assign(Object.assign({}, (state.context || {})), updates) });
511
+ return Object.assign(Object.assign({}, state), updates);
515
512
  }
516
513
  /**
517
- * Retrieves the current state of the workflow.
518
- * @returns {SharedState<T>} The current state
514
+ * Récupère l'état courant du workflow.
515
+ * @returns {SharedState<T>}
519
516
  */
520
517
  getState() {
521
518
  return this.currentState;
522
519
  }
523
520
  /**
524
- * Sets the state of the workflow.
525
- * @param {Partial<SharedState<T>>} state - The new state
521
+ * Définit le nouvel état courant du workflow et met à jour le contexte global.
522
+ * @param {Partial<SharedState<T>>} state
526
523
  */
527
524
  setState(state) {
528
525
  this.currentState = this.mergeStates(this.currentState, state);
529
- if (state.context) {
530
- Object.entries(state.context).forEach(([key, value]) => {
526
+ if (state) {
527
+ Object.entries(state).forEach(([key, value]) => {
531
528
  this.globalContext.set(key, value);
532
529
  });
533
530
  }
@@ -535,29 +532,95 @@ class GraphEngine {
535
532
  if (currentNode) {
536
533
  const node = this.nodes.get(currentNode);
537
534
  if (node) {
538
- node.state = Object.assign(Object.assign({}, (node.state || {})), (state.context || {}));
535
+ node.state = Object.assign(Object.assign({}, (node.state || {})), (state || {}));
539
536
  }
540
537
  }
541
538
  }
542
539
  /**
543
- * Merges two states.
544
- * @param {SharedState<T>} currentState - The current state
545
- * @param {Partial<SharedState<T>>} newState - The new state
546
- * @returns {SharedState<T>} The merged state
540
+ * Fusionne deux états.
541
+ * @param {SharedState<T>} currentState
542
+ * @param {Partial<SharedState<T>>} newState
543
+ * @returns {SharedState<T>}
547
544
  */
548
545
  mergeStates(currentState, newState) {
549
- return Object.assign(Object.assign({}, currentState), { context: Object.assign(Object.assign({}, (currentState.context || {})), (newState.context || {})) });
546
+ return Object.assign(Object.assign({}, currentState), (newState || {}));
550
547
  }
551
548
  /**
552
- * Updates the state of the workflow.
553
- * @param {Partial<SharedState<T>>} updates - The updates to apply
554
- * @returns {SharedState<T>} The updated state
549
+ * Met à jour l'état courant et le renvoie.
550
+ * @param {Partial<T>} updates
551
+ * @returns {SharedState<T>}
555
552
  */
556
553
  updateState(updates) {
557
554
  const currentState = this.getState();
558
- const newState = Object.assign(Object.assign({}, currentState), { context: Object.assign(Object.assign({}, currentState.context), (updates.context || {})) });
555
+ const newState = Object.assign(Object.assign({}, currentState), updates);
559
556
  this.setState(newState);
560
557
  return newState;
561
558
  }
559
+ /* =============================================
560
+ = MÉTHODES STATIQUES POUR PLUSIEURS GRAPHES =
561
+ ============================================= */
562
+ /**
563
+ * Exécute plusieurs GraphEngine en **séquence** (l'un après l'autre).
564
+ * @param graphs Liste des graphes à exécuter
565
+ * @param startNodes Noms des nœuds de départ correspondants
566
+ * @param initialStates États initiaux correspondants
567
+ * @param onStream Callback d'avancement
568
+ * @param onError Callback d'erreur
569
+ * @returns Tableau des états finaux de chaque graphe
570
+ */
571
+ static executeGraphsInSequence(graphs, startNodes, initialStates, onStream, onError) {
572
+ return __awaiter(this, void 0, void 0, function* () {
573
+ const finalStates = [];
574
+ for (let i = 0; i < graphs.length; i++) {
575
+ const graph = graphs[i];
576
+ const startNode = startNodes[i];
577
+ const initialState = initialStates[i];
578
+ const result = yield graph.execute(initialState, startNode, onStream, onError);
579
+ finalStates.push(result);
580
+ }
581
+ return finalStates;
582
+ });
583
+ }
584
+ /**
585
+ * Exécute plusieurs GraphEngine en **parallèle** (sans limite de concurrence).
586
+ * @param graphs Liste des graphes
587
+ * @param startNodes Noms des nœuds de départ
588
+ * @param initialStates États initiaux
589
+ * @param onStream Callback d'avancement
590
+ * @param onError Callback d'erreur
591
+ * @returns Tableau des états finaux de chaque graphe
592
+ */
593
+ static executeGraphsInParallel(graphs, startNodes, initialStates, onStream, onError) {
594
+ return __awaiter(this, void 0, void 0, function* () {
595
+ const promises = graphs.map((graph, index) => graph.execute(initialStates[index], startNodes[index], onStream, onError));
596
+ return Promise.all(promises);
597
+ });
598
+ }
599
+ /**
600
+ * Exécute plusieurs GraphEngine en parallèle **avec une limite de concurrence**.
601
+ * @param graphs Liste des graphes
602
+ * @param startNodes Noms des nœuds de départ
603
+ * @param initialStates États initiaux
604
+ * @param concurrencyLimit Limite de concurrence
605
+ * @param onStream Callback d'avancement
606
+ * @param onError Callback d'erreur
607
+ * @returns Tableau des états finaux de chaque graphe
608
+ */
609
+ static executeGraphsWithConcurrencyLimit(graphs, startNodes, initialStates, concurrencyLimit, onStream, onError) {
610
+ return __awaiter(this, void 0, void 0, function* () {
611
+ const results = [];
612
+ for (let i = 0; i < graphs.length; i += concurrencyLimit) {
613
+ const chunkGraphs = graphs.slice(i, i + concurrencyLimit);
614
+ const chunkStartNodes = startNodes.slice(i, i + concurrencyLimit);
615
+ const chunkInitialStates = initialStates.slice(i, i + concurrencyLimit);
616
+ const chunkPromises = chunkGraphs.map((graph, index) => {
617
+ return graph.execute(chunkInitialStates[index], chunkStartNodes[index], onStream, onError);
618
+ });
619
+ const chunkResults = yield Promise.all(chunkPromises);
620
+ results.push(...chunkResults);
621
+ }
622
+ return results;
623
+ });
624
+ }
562
625
  }
563
626
  exports.GraphEngine = GraphEngine;