@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
@@ -0,0 +1,563 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.GraphEngine = void 0;
16
+ const dotenv_1 = require("dotenv");
17
+ const events_1 = __importDefault(require("events"));
18
+ const zod_1 = require("zod");
19
+ (0, dotenv_1.configDotenv)();
20
+ /**
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.
23
+ *
24
+ * @template T - The type of data stored in the worflow's context
25
+ */
26
+ class GraphEngine {
27
+ /**
28
+ * Creates a new Graph instance.
29
+ *
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
34
+ */
35
+ constructor(definition, options) {
36
+ this.name = (definition === null || definition === void 0 ? void 0 : definition.name) || "anonymous";
37
+ this.eventEmitter = new events_1.default();
38
+ this.globalContext = new Map();
39
+ this.nodes = new Map();
40
+ this.executedNodes = new Set();
41
+ this.persistence = null;
42
+ this.notifier = null;
43
+ this.schema = options === null || options === void 0 ? void 0 : options.schema;
44
+ this.currentState = { context: {} };
45
+ if (definition) {
46
+ this.loadFromDefinition(definition);
47
+ }
48
+ if ((options === null || options === void 0 ? void 0 : options.autoDetectCycles) && this.checkForCycles()) {
49
+ throw new Error("Cycle detected in the workflow");
50
+ }
51
+ if (options === null || options === void 0 ? void 0 : options.initialState) {
52
+ this.setState(options.initialState);
53
+ }
54
+ }
55
+ /**
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
59
+ */
60
+ addToContext(key, value) {
61
+ this.globalContext.set(key, value);
62
+ }
63
+ /**
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
67
+ */
68
+ getContext(key) {
69
+ return this.globalContext.get(key);
70
+ }
71
+ /**
72
+ * Removes a value from the global context.
73
+ * @param {string} key - The key to remove
74
+ */
75
+ removeFromContext(key) {
76
+ this.globalContext.delete(key);
77
+ }
78
+ /**
79
+ * Sets the persistence layer for the worflow.
80
+ * @param {Persistence<T>} persistence - The persistence implementation
81
+ */
82
+ setPersistence(persistence) {
83
+ this.persistence = persistence;
84
+ }
85
+ /**
86
+ * Sets the real-time notifier for the worflow.
87
+ * @param {RealTimeNotifier} notifier - The notifier implementation
88
+ */
89
+ setNotifier(notifier) {
90
+ this.notifier = notifier;
91
+ }
92
+ /**
93
+ * Loads a worflow structure from a definition object.
94
+ * @private
95
+ * @param {GraphDefinition<T>} definition - The worflow definition
96
+ */
97
+ loadFromDefinition(definition) {
98
+ Object.entries(definition.nodes).forEach(([_, nodeConfig]) => {
99
+ this.addNode(nodeConfig, {
100
+ condition: nodeConfig.condition,
101
+ relationships: nodeConfig.relationships,
102
+ });
103
+ });
104
+ }
105
+ /**
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
112
+ */
113
+ isCyclic(nodeName, visited, recStack) {
114
+ if (!visited.has(nodeName)) {
115
+ visited.add(nodeName);
116
+ recStack.add(nodeName);
117
+ const currentNode = this.nodes.get(nodeName);
118
+ if (currentNode === null || currentNode === void 0 ? void 0 : currentNode.relationships) {
119
+ for (const relation of currentNode.relationships) {
120
+ const targetNode = relation.name;
121
+ if (!visited.has(targetNode) &&
122
+ this.isCyclic(targetNode, visited, recStack)) {
123
+ return true;
124
+ }
125
+ else if (recStack.has(targetNode)) {
126
+ return true;
127
+ }
128
+ }
129
+ }
130
+ }
131
+ recStack.delete(nodeName);
132
+ return false;
133
+ }
134
+ /**
135
+ * Checks if the worflow contains any cycles.
136
+ * @returns {boolean} True if cycles are detected, false otherwise
137
+ */
138
+ checkForCycles() {
139
+ const visited = new Set();
140
+ const recStack = new Set();
141
+ for (const nodeName of this.nodes.keys()) {
142
+ if (this.isCyclic(nodeName, visited, recStack)) {
143
+ return true;
144
+ }
145
+ }
146
+ return false;
147
+ }
148
+ /**
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
155
+ */
156
+ addNode(node, { condition, relationships, events, }) {
157
+ node.relationships = relationships;
158
+ node.condition = condition;
159
+ if (events) {
160
+ events.forEach((event) => {
161
+ this.eventEmitter.on(event, (data) => __awaiter(this, void 0, void 0, function* () {
162
+ const state = data.state || {};
163
+ yield this.execute(state, node.name);
164
+ }));
165
+ });
166
+ }
167
+ this.nodes.set(node.name, node);
168
+ }
169
+ /**
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
173
+ */
174
+ emit(eventName, data) {
175
+ this.eventEmitter.emit(eventName, data);
176
+ }
177
+ /**
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
182
+ */
183
+ addSubGraph(subGraph, entryNode, name) {
184
+ const subGraphNode = {
185
+ name: name,
186
+ execute: (state) => __awaiter(this, void 0, void 0, function* () {
187
+ yield subGraph.execute(state, entryNode);
188
+ return state;
189
+ }),
190
+ };
191
+ this.nodes.set(name, subGraphNode);
192
+ }
193
+ /**
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
199
+ */
200
+ execute(state, startNode, onStream, onError) {
201
+ return __awaiter(this, void 0, void 0, function* () {
202
+ var _a, _b;
203
+ try {
204
+ if (this.schema) {
205
+ try {
206
+ this.schema.parse(state.context);
207
+ }
208
+ catch (error) {
209
+ const validationError = new Error(`Initial state validation failed: ${error instanceof Error ? error.message : error}`);
210
+ if (onError)
211
+ onError(validationError, startNode, state);
212
+ throw validationError;
213
+ }
214
+ }
215
+ this.setState(state);
216
+ let currentNodeName = startNode;
217
+ while (currentNodeName) {
218
+ this.executedNodes.add(currentNodeName);
219
+ const currentNode = this.nodes.get(currentNodeName);
220
+ if (!currentNode)
221
+ throw new Error(`Node ${currentNodeName} not found.`);
222
+ if (currentNode.condition &&
223
+ !currentNode.condition(this.currentState)) {
224
+ break;
225
+ }
226
+ try {
227
+ if (this.notifier) {
228
+ this.notifier.notify("nodeExecutionStarted", {
229
+ workflow: this.name,
230
+ node: currentNodeName,
231
+ });
232
+ }
233
+ const params = (_a = currentNode.schema) === null || _a === void 0 ? void 0 : _a.parse(this.currentState);
234
+ const newState = yield currentNode.execute(params || {}, this.currentState);
235
+ if (newState) {
236
+ this.setState(newState);
237
+ if (onStream)
238
+ onStream(this.currentState);
239
+ }
240
+ if (this.persistence) {
241
+ yield this.persistence.saveState(this.name, this.currentState, currentNodeName);
242
+ }
243
+ if (this.notifier) {
244
+ yield this.notifier.notify("nodeExecutionCompleted", {
245
+ workflow: this.name,
246
+ node: currentNodeName,
247
+ state: this.currentState,
248
+ });
249
+ }
250
+ }
251
+ catch (error) {
252
+ if (onError)
253
+ onError(error, currentNodeName, this.currentState);
254
+ if (this.notifier) {
255
+ this.notifier.notify("nodeExecutionFailed", {
256
+ workflow: this.name,
257
+ node: currentNodeName,
258
+ state: this.currentState,
259
+ error,
260
+ });
261
+ }
262
+ break;
263
+ }
264
+ const relationsNodes = currentNode.relationships || [];
265
+ if (relationsNodes.length > 1) {
266
+ yield Promise.all(relationsNodes.map((relation) => this.execute(this.currentState, relation.name, onStream, onError)));
267
+ break;
268
+ }
269
+ else {
270
+ currentNodeName = ((_b = relationsNodes[0]) === null || _b === void 0 ? void 0 : _b.name) || "";
271
+ }
272
+ }
273
+ return this.getState();
274
+ }
275
+ catch (error) {
276
+ if (onError) {
277
+ onError(error, startNode, state);
278
+ }
279
+ throw error;
280
+ }
281
+ });
282
+ }
283
+ /**
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
290
+ */
291
+ executeParallel(state_1, nodeNames_1) {
292
+ return __awaiter(this, arguments, void 0, function* (state, nodeNames, concurrencyLimit = 5, onStream, onError) {
293
+ const executeWithLimit = (nodeName) => __awaiter(this, void 0, void 0, function* () {
294
+ yield this.execute(state, nodeName, onStream, onError);
295
+ });
296
+ const chunks = [];
297
+ for (let i = 0; i < nodeNames.length; i += concurrencyLimit) {
298
+ chunks.push(nodeNames.slice(i, i + concurrencyLimit));
299
+ }
300
+ for (const chunk of chunks) {
301
+ yield Promise.all(chunk.map(executeWithLimit));
302
+ }
303
+ });
304
+ }
305
+ /**
306
+ * Updates the worflow structure with a new definition.
307
+ * @param {GraphDefinition<T>} definition - The new worflow definition
308
+ */
309
+ updateGraph(definition) {
310
+ Object.entries(definition.nodes).forEach(([_, nodeConfig]) => {
311
+ if (this.nodes.has(nodeConfig.name)) {
312
+ const existingNode = this.nodes.get(nodeConfig.name);
313
+ existingNode.relationships =
314
+ nodeConfig.relationships || existingNode.relationships;
315
+ existingNode.condition = nodeConfig.condition || existingNode.condition;
316
+ }
317
+ else {
318
+ this.addNode(nodeConfig, {
319
+ condition: nodeConfig.condition,
320
+ relationships: nodeConfig.relationships,
321
+ });
322
+ }
323
+ });
324
+ }
325
+ /**
326
+ * Replace the worflow with a new definition.
327
+ * @param {GraphDefinition<T>} definition - The new worflow definition
328
+ */
329
+ replaceGraph(definition) {
330
+ this.nodes.clear();
331
+ this.loadFromDefinition(definition);
332
+ }
333
+ /**
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
342
+ */
343
+ generateMermaidDiagram(title) {
344
+ const lines = ["flowchart TD"];
345
+ if (title) {
346
+ lines.push(` subgraph ${title}`);
347
+ }
348
+ // Add nodes with styling
349
+ this.nodes.forEach((node, nodeName) => {
350
+ const hasEvents = node.events && node.events.length > 0;
351
+ const hasCondition = !!node.condition;
352
+ // Style nodes based on their properties
353
+ let style = "";
354
+ if (hasEvents) {
355
+ style = "style " + nodeName + " fill:#FFD700,stroke:#DAA520"; // Yellow for event nodes
356
+ }
357
+ else if (hasCondition) {
358
+ style = "style " + nodeName + " fill:#FFA500,stroke:#FF8C00"; // Orange for conditional nodes
359
+ }
360
+ // Add node definition
361
+ lines.push(` ${nodeName}[${nodeName}]`);
362
+ if (style) {
363
+ lines.push(` ${style}`);
364
+ }
365
+ });
366
+ // Add connections
367
+ this.nodes.forEach((node, nodeName) => {
368
+ if (node.relationships) {
369
+ node.relationships.forEach((relationsNode) => {
370
+ let connectionStyle = "";
371
+ if (node.condition) {
372
+ connectionStyle = "---|condition|"; // Add label for conditional connections
373
+ }
374
+ else {
375
+ connectionStyle = "-->"; // Normal connection
376
+ }
377
+ lines.push(` ${nodeName} ${connectionStyle} ${relationsNode}`);
378
+ });
379
+ }
380
+ // Add event connections if any
381
+ if (node.events && node.events.length > 0) {
382
+ node.events.forEach((event) => {
383
+ const eventNodeId = `${event}_event`;
384
+ lines.push(` ${eventNodeId}((${event})):::event`);
385
+ lines.push(` ${eventNodeId} -.->|trigger| ${nodeName}`);
386
+ });
387
+ // Add style class for event nodes
388
+ lines.push(" classDef event fill:#FFD700,stroke:#DAA520");
389
+ }
390
+ });
391
+ if (title) {
392
+ lines.push(" end");
393
+ }
394
+ return lines.join("\n");
395
+ }
396
+ /**
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
401
+ */
402
+ visualize(title) {
403
+ const diagram = this.generateMermaidDiagram(title);
404
+ console.log("To visualize this worflow, use a Mermaid-compatible renderer with this syntax:");
405
+ console.log("\n```mermaid");
406
+ console.log(diagram);
407
+ console.log("```\n");
408
+ }
409
+ exportGraphToJson(worflow) {
410
+ const result = {
411
+ worflowName: worflow.name,
412
+ entryNode: worflow.entryNode,
413
+ nodes: Object.entries(worflow.nodes).reduce((acc, [key, node]) => {
414
+ acc[key] = {
415
+ name: node.name,
416
+ description: node.description || "No description provided",
417
+ execute: node.execute.name,
418
+ condition: node.condition ? node.condition.toString() : "None",
419
+ relationships: node.relationships || [],
420
+ };
421
+ return acc;
422
+ }, {}),
423
+ };
424
+ return JSON.stringify(result, null, 2);
425
+ }
426
+ /**
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
431
+ */
432
+ visualizeSchema() {
433
+ const output = [];
434
+ output.push(`šŸ“‹ Graph: ${this.name}`);
435
+ output.push("=".repeat(50));
436
+ if (this.schema) {
437
+ output.push("šŸ”· Global Schema:");
438
+ output.push("-".repeat(30));
439
+ if (this.schema instanceof zod_1.z.ZodObject) {
440
+ const shape = this.schema.shape;
441
+ Object.entries(shape).forEach(([key, value]) => {
442
+ const description = this.describeZodType(value, 1);
443
+ output.push(`${key}:`);
444
+ output.push(description);
445
+ });
446
+ }
447
+ output.push("");
448
+ }
449
+ output.push("šŸ”· Nodes:");
450
+ output.push("-".repeat(30));
451
+ this.nodes.forEach((node, nodeName) => {
452
+ output.push(`\nšŸ“ Node: ${nodeName}`);
453
+ output.push(`Description: ${node.description || "No description provided"}`);
454
+ if (node.relationships && node.relationships.length > 0) {
455
+ output.push(`Next nodes: ${node.relationships.join(", ")}`);
456
+ }
457
+ output.push("");
458
+ });
459
+ return output.join("\n");
460
+ }
461
+ /**
462
+ * Recursively describes a Zod type.
463
+ */
464
+ describeZodType(type, indent = 0) {
465
+ const padding = " ".repeat(indent);
466
+ if (type instanceof zod_1.z.ZodObject) {
467
+ const shape = type.shape;
468
+ const lines = [];
469
+ Object.entries(shape).forEach(([key, value]) => {
470
+ const isOptional = value instanceof zod_1.z.ZodOptional;
471
+ const actualType = isOptional
472
+ ? value.unwrap()
473
+ : value;
474
+ const description = this.describeZodType(actualType, indent + 1);
475
+ lines.push(`${padding}${key}${isOptional ? "?" : ""}: ${description}`);
476
+ });
477
+ return lines.join("\n");
478
+ }
479
+ if (type instanceof zod_1.z.ZodArray) {
480
+ const elementType = this.describeZodType(type.element, indent);
481
+ return `Array<${elementType}>`;
482
+ }
483
+ if (type instanceof zod_1.z.ZodString) {
484
+ const checks = type._def.checks || [];
485
+ const constraints = checks
486
+ .map((check) => {
487
+ if (check.kind === "url")
488
+ return "url";
489
+ if (check.kind === "email")
490
+ return "email";
491
+ return check.kind;
492
+ })
493
+ .join(", ");
494
+ return constraints ? `string (${constraints})` : "string";
495
+ }
496
+ if (type instanceof zod_1.z.ZodNumber) {
497
+ return "number";
498
+ }
499
+ if (type instanceof zod_1.z.ZodBoolean) {
500
+ return "boolean";
501
+ }
502
+ if (type instanceof zod_1.z.ZodOptional) {
503
+ return `${this.describeZodType(type.unwrap(), indent)} (optional)`;
504
+ }
505
+ return type.constructor.name.replace("Zod", "") || "unknown";
506
+ }
507
+ /**
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
512
+ */
513
+ updateNodeState(state, updates) {
514
+ return Object.assign(Object.assign({}, state), { context: Object.assign(Object.assign({}, (state.context || {})), updates) });
515
+ }
516
+ /**
517
+ * Retrieves the current state of the workflow.
518
+ * @returns {SharedState<T>} The current state
519
+ */
520
+ getState() {
521
+ return this.currentState;
522
+ }
523
+ /**
524
+ * Sets the state of the workflow.
525
+ * @param {Partial<SharedState<T>>} state - The new state
526
+ */
527
+ setState(state) {
528
+ this.currentState = this.mergeStates(this.currentState, state);
529
+ if (state.context) {
530
+ Object.entries(state.context).forEach(([key, value]) => {
531
+ this.globalContext.set(key, value);
532
+ });
533
+ }
534
+ const currentNode = Array.from(this.executedNodes).pop();
535
+ if (currentNode) {
536
+ const node = this.nodes.get(currentNode);
537
+ if (node) {
538
+ node.state = Object.assign(Object.assign({}, (node.state || {})), (state.context || {}));
539
+ }
540
+ }
541
+ }
542
+ /**
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
547
+ */
548
+ mergeStates(currentState, newState) {
549
+ return Object.assign(Object.assign({}, currentState), { context: Object.assign(Object.assign({}, (currentState.context || {})), (newState.context || {})) });
550
+ }
551
+ /**
552
+ * Updates the state of the workflow.
553
+ * @param {Partial<SharedState<T>>} updates - The updates to apply
554
+ * @returns {SharedState<T>} The updated state
555
+ */
556
+ updateState(updates) {
557
+ const currentState = this.getState();
558
+ const newState = Object.assign(Object.assign({}, currentState), { context: Object.assign(Object.assign({}, currentState.context), (updates.context || {})) });
559
+ this.setState(newState);
560
+ return newState;
561
+ }
562
+ }
563
+ exports.GraphEngine = GraphEngine;
package/dist/index.js CHANGED
@@ -14,10 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./agent"), exports);
18
- __exportStar(require("./llm/interpreter"), exports);
19
- __exportStar(require("./llm/interpreter/context"), exports);
20
- __exportStar(require("./llm/orchestrator"), exports);
17
+ __exportStar(require("./graph/controller"), exports);
18
+ __exportStar(require("./graph/engine"), exports);
19
+ __exportStar(require("./memory"), exports);
20
+ __exportStar(require("./memory/adapters/meilisearch"), exports);
21
+ __exportStar(require("./memory/adapters/redis"), exports);
22
+ __exportStar(require("./interfaces"), exports);
21
23
  __exportStar(require("./types"), exports);
22
- __exportStar(require("./memory/cache"), exports);
23
- __exportStar(require("./memory/persistent"), exports);