@ai.ntellect/core 1.0.0 → 1.1.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 (435) hide show
  1. package/.mocharc.json +6 -0
  2. package/AGENTS.md +50 -0
  3. package/ARCHITECTURE.md +58 -0
  4. package/BENCHMARK.md +38 -0
  5. package/CHANGELOG.md +224 -0
  6. package/README.md +363 -142
  7. package/agent/agent-workflow.ts +569 -0
  8. package/agent/agent.ts +183 -0
  9. package/agent/base/executor.ts +103 -0
  10. package/agent/base/index.ts +87 -0
  11. package/agent/entity-resolver/confidence.ts +54 -0
  12. package/agent/entity-resolver/entity-index.ts +241 -0
  13. package/agent/entity-resolver/explore-strategy.ts +82 -0
  14. package/agent/entity-resolver/index.ts +22 -0
  15. package/agent/entity-resolver/resolver.ts +193 -0
  16. package/agent/entity-resolver/scorer.ts +211 -0
  17. package/agent/entity-resolver/types.ts +98 -0
  18. package/agent/generic-executor.ts +713 -0
  19. package/agent/handlers/cognitive-handler.ts +197 -0
  20. package/agent/handlers/index.ts +1 -0
  21. package/agent/handoff.ts +58 -0
  22. package/agent/llm-factory.ts +343 -0
  23. package/agent/orchestrator.ts +45 -0
  24. package/agent/prompt-builder.ts +78 -0
  25. package/agent/registry.ts +64 -0
  26. package/agent/tools/file-system.ts +471 -0
  27. package/agent/tools/index.ts +23 -0
  28. package/agent/tools/logger.ts +105 -0
  29. package/agent/tools/tool-resolver.ts +104 -0
  30. package/benchmark/cortexflow-workflow.ts +182 -0
  31. package/benchmark/langgraph-workflow.ts +201 -0
  32. package/benchmark/llm-client.ts +76 -0
  33. package/benchmark/run-benchmark.ts +222 -0
  34. package/cli-dev.ts +419 -0
  35. package/dist/agent/agent-workflow.d.ts +41 -0
  36. package/dist/agent/agent-workflow.d.ts.map +1 -0
  37. package/dist/agent/agent-workflow.js +560 -0
  38. package/dist/agent/agent-workflow.js.map +1 -0
  39. package/dist/agent/agent.d.ts +38 -0
  40. package/dist/agent/agent.d.ts.map +1 -0
  41. package/dist/agent/agent.js +149 -0
  42. package/dist/agent/agent.js.map +1 -0
  43. package/dist/agent/base/executor.d.ts +51 -0
  44. package/dist/agent/base/executor.d.ts.map +1 -0
  45. package/dist/agent/base/executor.js +69 -0
  46. package/dist/agent/base/executor.js.map +1 -0
  47. package/dist/agent/base/index.d.ts +30 -0
  48. package/dist/agent/base/index.d.ts.map +1 -0
  49. package/dist/agent/base/index.js +88 -0
  50. package/dist/agent/base/index.js.map +1 -0
  51. package/dist/agent/entity-resolver/confidence.d.ts +4 -0
  52. package/dist/agent/entity-resolver/confidence.d.ts.map +1 -0
  53. package/dist/agent/entity-resolver/confidence.js +47 -0
  54. package/dist/agent/entity-resolver/confidence.js.map +1 -0
  55. package/dist/agent/entity-resolver/entity-index.d.ts +40 -0
  56. package/dist/agent/entity-resolver/entity-index.d.ts.map +1 -0
  57. package/dist/agent/entity-resolver/entity-index.js +244 -0
  58. package/dist/agent/entity-resolver/entity-index.js.map +1 -0
  59. package/dist/agent/entity-resolver/explore-strategy.d.ts +13 -0
  60. package/dist/agent/entity-resolver/explore-strategy.d.ts.map +1 -0
  61. package/dist/agent/entity-resolver/explore-strategy.js +109 -0
  62. package/dist/agent/entity-resolver/explore-strategy.js.map +1 -0
  63. package/dist/agent/entity-resolver/index.d.ts +8 -0
  64. package/dist/agent/entity-resolver/index.d.ts.map +1 -0
  65. package/dist/agent/entity-resolver/index.js +16 -0
  66. package/dist/agent/entity-resolver/index.js.map +1 -0
  67. package/dist/agent/entity-resolver/resolver.d.ts +18 -0
  68. package/dist/agent/entity-resolver/resolver.d.ts.map +1 -0
  69. package/dist/agent/entity-resolver/resolver.js +158 -0
  70. package/dist/agent/entity-resolver/resolver.js.map +1 -0
  71. package/dist/agent/entity-resolver/scorer.d.ts +3 -0
  72. package/dist/agent/entity-resolver/scorer.d.ts.map +1 -0
  73. package/dist/agent/entity-resolver/scorer.js +182 -0
  74. package/dist/agent/entity-resolver/scorer.js.map +1 -0
  75. package/dist/agent/entity-resolver/types.d.ts +89 -0
  76. package/dist/agent/entity-resolver/types.d.ts.map +1 -0
  77. package/dist/agent/entity-resolver/types.js +3 -0
  78. package/dist/agent/entity-resolver/types.js.map +1 -0
  79. package/dist/agent/generic-executor.d.ts +68 -0
  80. package/dist/agent/generic-executor.d.ts.map +1 -0
  81. package/dist/agent/generic-executor.js +620 -0
  82. package/dist/agent/generic-executor.js.map +1 -0
  83. package/dist/agent/handlers/cognitive-handler.d.ts +44 -0
  84. package/dist/agent/handlers/cognitive-handler.d.ts.map +1 -0
  85. package/dist/agent/handlers/cognitive-handler.js +172 -0
  86. package/dist/agent/handlers/cognitive-handler.js.map +1 -0
  87. package/dist/agent/handlers/index.d.ts +2 -0
  88. package/dist/agent/handlers/index.d.ts.map +1 -0
  89. package/dist/agent/handlers/index.js +7 -0
  90. package/dist/agent/handlers/index.js.map +1 -0
  91. package/dist/agent/handoff.d.ts +12 -0
  92. package/dist/agent/handoff.d.ts.map +1 -0
  93. package/dist/agent/handoff.js +62 -0
  94. package/dist/agent/handoff.js.map +1 -0
  95. package/dist/agent/llm-factory.d.ts +19 -0
  96. package/dist/agent/llm-factory.d.ts.map +1 -0
  97. package/dist/agent/llm-factory.js +297 -0
  98. package/dist/agent/llm-factory.js.map +1 -0
  99. package/dist/agent/orchestrator.d.ts +18 -0
  100. package/dist/agent/orchestrator.d.ts.map +1 -0
  101. package/dist/agent/orchestrator.js +44 -0
  102. package/dist/agent/orchestrator.js.map +1 -0
  103. package/dist/agent/prompt-builder.d.ts +35 -0
  104. package/dist/agent/prompt-builder.d.ts.map +1 -0
  105. package/dist/agent/prompt-builder.js +76 -0
  106. package/dist/agent/prompt-builder.js.map +1 -0
  107. package/dist/agent/registry.d.ts +19 -0
  108. package/dist/agent/registry.d.ts.map +1 -0
  109. package/dist/agent/registry.js +48 -0
  110. package/dist/agent/registry.js.map +1 -0
  111. package/dist/agent/tools/file-system.d.ts +11 -0
  112. package/dist/agent/tools/file-system.d.ts.map +1 -0
  113. package/dist/agent/tools/file-system.js +528 -0
  114. package/dist/agent/tools/file-system.js.map +1 -0
  115. package/dist/agent/tools/index.d.ts +4 -0
  116. package/dist/agent/tools/index.d.ts.map +1 -0
  117. package/dist/agent/tools/index.js +20 -0
  118. package/dist/agent/tools/index.js.map +1 -0
  119. package/dist/agent/tools/logger.d.ts +33 -0
  120. package/dist/agent/tools/logger.d.ts.map +1 -0
  121. package/dist/agent/tools/logger.js +86 -0
  122. package/dist/agent/tools/logger.js.map +1 -0
  123. package/dist/agent/tools/tool-resolver.d.ts +7 -0
  124. package/dist/agent/tools/tool-resolver.d.ts.map +1 -0
  125. package/dist/agent/tools/tool-resolver.js +122 -0
  126. package/dist/agent/tools/tool-resolver.js.map +1 -0
  127. package/dist/execution/adapters/in-memory-checkpoint.d.ts +11 -0
  128. package/dist/execution/adapters/in-memory-checkpoint.d.ts.map +1 -0
  129. package/dist/execution/adapters/in-memory-checkpoint.js +54 -0
  130. package/dist/execution/adapters/in-memory-checkpoint.js.map +1 -0
  131. package/dist/execution/compiler.d.ts +8 -0
  132. package/dist/execution/compiler.d.ts.map +1 -0
  133. package/dist/execution/compiler.js +50 -0
  134. package/dist/execution/compiler.js.map +1 -0
  135. package/dist/execution/controller.d.ts +30 -0
  136. package/dist/execution/controller.d.ts.map +1 -0
  137. package/dist/execution/controller.js +80 -0
  138. package/dist/execution/controller.js.map +1 -0
  139. package/dist/execution/event-manager.d.ts +29 -0
  140. package/dist/execution/event-manager.d.ts.map +1 -0
  141. package/dist/execution/event-manager.js +264 -0
  142. package/dist/execution/event-manager.js.map +1 -0
  143. package/dist/execution/index.d.ts +221 -0
  144. package/dist/execution/index.d.ts.map +1 -0
  145. package/dist/execution/index.js +638 -0
  146. package/dist/execution/index.js.map +1 -0
  147. package/dist/execution/logger.d.ts +46 -0
  148. package/dist/execution/logger.d.ts.map +1 -0
  149. package/dist/execution/logger.js +69 -0
  150. package/dist/execution/logger.js.map +1 -0
  151. package/dist/execution/node.d.ts +65 -0
  152. package/dist/execution/node.d.ts.map +1 -0
  153. package/dist/execution/node.js +250 -0
  154. package/dist/execution/node.js.map +1 -0
  155. package/dist/execution/observer.d.ts +38 -0
  156. package/dist/execution/observer.d.ts.map +1 -0
  157. package/dist/execution/observer.js +111 -0
  158. package/dist/execution/observer.js.map +1 -0
  159. package/dist/execution/planner.d.ts +14 -0
  160. package/dist/execution/planner.d.ts.map +1 -0
  161. package/dist/execution/planner.js +43 -0
  162. package/dist/execution/planner.js.map +1 -0
  163. package/dist/execution/reducer.d.ts +19 -0
  164. package/dist/execution/reducer.d.ts.map +1 -0
  165. package/dist/execution/reducer.js +61 -0
  166. package/dist/execution/reducer.js.map +1 -0
  167. package/dist/execution/registry.d.ts +38 -0
  168. package/dist/execution/registry.d.ts.map +1 -0
  169. package/dist/execution/registry.js +63 -0
  170. package/dist/execution/registry.js.map +1 -0
  171. package/dist/execution/send-api.d.ts +24 -0
  172. package/dist/execution/send-api.d.ts.map +1 -0
  173. package/dist/execution/send-api.js +52 -0
  174. package/dist/execution/send-api.js.map +1 -0
  175. package/dist/execution/types.parallel.d.ts +61 -0
  176. package/dist/execution/types.parallel.d.ts.map +1 -0
  177. package/dist/execution/types.parallel.js +3 -0
  178. package/dist/execution/types.parallel.js.map +1 -0
  179. package/dist/execution/visualizer.d.ts +35 -0
  180. package/dist/execution/visualizer.d.ts.map +1 -0
  181. package/dist/execution/visualizer.js +131 -0
  182. package/dist/execution/visualizer.js.map +1 -0
  183. package/dist/index.d.ts +47 -0
  184. package/dist/index.d.ts.map +1 -0
  185. package/dist/index.js +78 -0
  186. package/dist/index.js.map +1 -0
  187. package/dist/interfaces/index.d.ts +487 -0
  188. package/dist/interfaces/index.d.ts.map +1 -0
  189. package/dist/interfaces/index.js +75 -0
  190. package/dist/interfaces/index.js.map +1 -0
  191. package/dist/modules/agenda/adapters/node-cron/index.d.ts +17 -0
  192. package/dist/modules/agenda/adapters/node-cron/index.d.ts.map +1 -0
  193. package/dist/modules/agenda/adapters/node-cron/index.js +30 -0
  194. package/dist/modules/agenda/adapters/node-cron/index.js.map +1 -0
  195. package/dist/modules/agenda/index.d.ts +63 -0
  196. package/dist/modules/agenda/index.d.ts.map +1 -0
  197. package/dist/modules/agenda/index.js +141 -0
  198. package/dist/modules/agenda/index.js.map +1 -0
  199. package/dist/modules/cli/index.d.ts +13 -0
  200. package/dist/modules/cli/index.d.ts.map +1 -0
  201. package/dist/modules/cli/index.js +672 -0
  202. package/dist/modules/cli/index.js.map +1 -0
  203. package/dist/modules/embedding/adapters/ai/index.d.ts +29 -0
  204. package/dist/modules/embedding/adapters/ai/index.d.ts.map +1 -0
  205. package/dist/modules/embedding/adapters/ai/index.js +58 -0
  206. package/dist/modules/embedding/adapters/ai/index.js.map +1 -0
  207. package/dist/modules/embedding/index.d.ts +36 -0
  208. package/dist/modules/embedding/index.d.ts.map +1 -0
  209. package/dist/modules/embedding/index.js +60 -0
  210. package/dist/modules/embedding/index.js.map +1 -0
  211. package/dist/modules/nlp/engine.d.ts +126 -0
  212. package/dist/modules/nlp/engine.d.ts.map +1 -0
  213. package/dist/modules/nlp/engine.js +299 -0
  214. package/dist/modules/nlp/engine.js.map +1 -0
  215. package/dist/modules/nlp/index.d.ts +27 -0
  216. package/dist/modules/nlp/index.d.ts.map +1 -0
  217. package/dist/modules/nlp/index.js +56 -0
  218. package/dist/modules/nlp/index.js.map +1 -0
  219. package/dist/persistence/index.d.ts +12 -0
  220. package/dist/persistence/index.d.ts.map +1 -0
  221. package/dist/persistence/index.js +24 -0
  222. package/dist/persistence/index.js.map +1 -0
  223. package/dist/persistence/neo4j/driver.d.ts +26 -0
  224. package/dist/persistence/neo4j/driver.d.ts.map +1 -0
  225. package/dist/persistence/neo4j/driver.js +64 -0
  226. package/dist/persistence/neo4j/driver.js.map +1 -0
  227. package/dist/persistence/neo4j/entity-store.d.ts +15 -0
  228. package/dist/persistence/neo4j/entity-store.d.ts.map +1 -0
  229. package/dist/persistence/neo4j/entity-store.js +136 -0
  230. package/dist/persistence/neo4j/entity-store.js.map +1 -0
  231. package/dist/persistence/neo4j/execution-tracer.d.ts +19 -0
  232. package/dist/persistence/neo4j/execution-tracer.d.ts.map +1 -0
  233. package/dist/persistence/neo4j/execution-tracer.js +166 -0
  234. package/dist/persistence/neo4j/execution-tracer.js.map +1 -0
  235. package/dist/persistence/neo4j/memory-adapter.d.ts +35 -0
  236. package/dist/persistence/neo4j/memory-adapter.d.ts.map +1 -0
  237. package/dist/persistence/neo4j/memory-adapter.js +252 -0
  238. package/dist/persistence/neo4j/memory-adapter.js.map +1 -0
  239. package/dist/persistence/neo4j/petri-checkpoint-adapter.d.ts +22 -0
  240. package/dist/persistence/neo4j/petri-checkpoint-adapter.d.ts.map +1 -0
  241. package/dist/persistence/neo4j/petri-checkpoint-adapter.js +141 -0
  242. package/dist/persistence/neo4j/petri-checkpoint-adapter.js.map +1 -0
  243. package/dist/pipeline/agent-pipeline.d.ts +99 -0
  244. package/dist/pipeline/agent-pipeline.d.ts.map +1 -0
  245. package/dist/pipeline/agent-pipeline.js +356 -0
  246. package/dist/pipeline/agent-pipeline.js.map +1 -0
  247. package/dist/routing/checkpoint-adapter.d.ts +30 -0
  248. package/dist/routing/checkpoint-adapter.d.ts.map +1 -0
  249. package/dist/routing/checkpoint-adapter.js +83 -0
  250. package/dist/routing/checkpoint-adapter.js.map +1 -0
  251. package/dist/routing/documentation-generator.d.ts +47 -0
  252. package/dist/routing/documentation-generator.d.ts.map +1 -0
  253. package/dist/routing/documentation-generator.js +320 -0
  254. package/dist/routing/documentation-generator.js.map +1 -0
  255. package/dist/routing/index.d.ts +38 -0
  256. package/dist/routing/index.d.ts.map +1 -0
  257. package/dist/routing/index.js +375 -0
  258. package/dist/routing/index.js.map +1 -0
  259. package/dist/routing/intent-classifier.d.ts +206 -0
  260. package/dist/routing/intent-classifier.d.ts.map +1 -0
  261. package/dist/routing/intent-classifier.js +267 -0
  262. package/dist/routing/intent-classifier.js.map +1 -0
  263. package/dist/routing/matrix.d.ts +6 -0
  264. package/dist/routing/matrix.d.ts.map +1 -0
  265. package/dist/routing/matrix.js +131 -0
  266. package/dist/routing/matrix.js.map +1 -0
  267. package/dist/routing/orchestrator.d.ts +87 -0
  268. package/dist/routing/orchestrator.d.ts.map +1 -0
  269. package/dist/routing/orchestrator.js +425 -0
  270. package/dist/routing/orchestrator.js.map +1 -0
  271. package/dist/routing/postgres-checkpoint-adapter.d.ts +32 -0
  272. package/dist/routing/postgres-checkpoint-adapter.d.ts.map +1 -0
  273. package/dist/routing/postgres-checkpoint-adapter.js +167 -0
  274. package/dist/routing/postgres-checkpoint-adapter.js.map +1 -0
  275. package/dist/routing/redis-checkpoint-adapter.d.ts +34 -0
  276. package/dist/routing/redis-checkpoint-adapter.d.ts.map +1 -0
  277. package/dist/routing/redis-checkpoint-adapter.js +170 -0
  278. package/dist/routing/redis-checkpoint-adapter.js.map +1 -0
  279. package/dist/routing/types.d.ts +49 -0
  280. package/dist/routing/types.d.ts.map +1 -0
  281. package/dist/routing/types.js +3 -0
  282. package/dist/routing/types.js.map +1 -0
  283. package/dist/types/agent.d.ts +289 -0
  284. package/dist/types/agent.d.ts.map +1 -0
  285. package/dist/types/agent.js +78 -0
  286. package/dist/types/agent.js.map +1 -0
  287. package/dist/types/index.d.ts +343 -0
  288. package/dist/types/index.d.ts.map +1 -0
  289. package/dist/types/index.js +3 -0
  290. package/dist/types/index.js.map +1 -0
  291. package/dist/utils/generate-action-schema.d.ts +4 -0
  292. package/dist/utils/generate-action-schema.d.ts.map +1 -0
  293. package/dist/utils/generate-action-schema.js +46 -0
  294. package/dist/utils/generate-action-schema.js.map +1 -0
  295. package/dist/utils/header-builder.d.ts +12 -0
  296. package/dist/utils/header-builder.d.ts.map +1 -0
  297. package/dist/utils/header-builder.js +35 -0
  298. package/dist/utils/header-builder.js.map +1 -0
  299. package/dist/utils/logger.d.ts +27 -0
  300. package/dist/utils/logger.d.ts.map +1 -0
  301. package/dist/utils/logger.js +45 -0
  302. package/dist/utils/logger.js.map +1 -0
  303. package/docs/.gitbook/assets/image (1).png +0 -0
  304. package/docs/.gitbook/assets/image (2).png +0 -0
  305. package/docs/.gitbook/assets/image (3).png +0 -0
  306. package/docs/.gitbook/assets/image (4).png +0 -0
  307. package/docs/.gitbook/assets/image (5).png +0 -0
  308. package/docs/.gitbook/assets/image (6).png +0 -0
  309. package/docs/.gitbook/assets/image.png +0 -0
  310. package/docs/README.md +57 -0
  311. package/docs/SUMMARY.md +34 -0
  312. package/docs/cas-dusages.md +69 -0
  313. package/docs/cli/README.md +65 -0
  314. package/docs/concepts-cles.md +50 -0
  315. package/docs/core/architecture.md +87 -0
  316. package/docs/core/benchmark.md +59 -0
  317. package/docs/core/checkpoint.md +72 -0
  318. package/docs/core/documentation.md +55 -0
  319. package/docs/core/graphcontroller.md +63 -0
  320. package/docs/core/graphflow.md +137 -0
  321. package/docs/core/introduction.md +41 -0
  322. package/docs/core/les-evenements.md +95 -0
  323. package/docs/modules/agenda/README.md +63 -0
  324. package/docs/modules/agenda/interface-iagenda.md +170 -0
  325. package/docs/modules/agenda/les-adaptateurs/README.md +237 -0
  326. package/docs/modules/agenda/les-adaptateurs/nodecronadapter.md +91 -0
  327. package/docs/modules/introduction.md +55 -0
  328. package/docs/modules/les-adaptateurs.md +52 -0
  329. package/docs/modules/memoire/README.md +68 -0
  330. package/docs/modules/memoire/interface-imemory.md +183 -0
  331. package/docs/modules/memoire/les-adaptateurs/README.md +209 -0
  332. package/docs/modules/memoire/les-adaptateurs/inmemoryadapter.md +110 -0
  333. package/docs/modules/memoire/les-adaptateurs/meilisearchadapter.md +147 -0
  334. package/docs/modules/memoire/les-adaptateurs/redisadapter.md +212 -0
  335. package/docs/modules/nlp/README.md +44 -0
  336. package/docs/philosophie.md +51 -0
  337. package/docs/tutoriels/ajouter-des-conditions.md +150 -0
  338. package/docs/tutoriels/branching.md +194 -0
  339. package/docs/tutoriels/checkpoint-usage.md +99 -0
  340. package/docs/tutoriels/creer-agent-onchain.md +1041 -0
  341. package/docs/tutoriels/creer-un-agent.md +108 -0
  342. package/docs/tutoriels/creer-un-graphe-simple.md +92 -0
  343. package/docs/tutoriels/gerer-les-erreurs.md +124 -0
  344. package/docs/tutoriels/pour-commencer.md +73 -0
  345. package/docs/tutoriels/retry.md +166 -0
  346. package/execution/adapters/in-memory-checkpoint.ts +35 -0
  347. package/execution/compiler.ts +47 -0
  348. package/execution/controller.ts +84 -0
  349. package/execution/event-manager.ts +331 -0
  350. package/execution/index.ts +800 -0
  351. package/execution/logger.ts +70 -0
  352. package/execution/node.ts +315 -0
  353. package/execution/observer.ts +192 -0
  354. package/execution/planner.ts +40 -0
  355. package/execution/reducer.ts +73 -0
  356. package/execution/registry.ts +86 -0
  357. package/execution/send-api.ts +58 -0
  358. package/execution/types.parallel.ts +81 -0
  359. package/execution/visualizer.ts +158 -0
  360. package/index.ts +55 -465
  361. package/interfaces/index.ts +597 -0
  362. package/modules/agenda/adapters/node-cron/index.ts +25 -0
  363. package/modules/agenda/index.ts +146 -0
  364. package/modules/cli/index.ts +580 -0
  365. package/modules/embedding/adapters/ai/index.ts +42 -0
  366. package/modules/embedding/index.ts +45 -0
  367. package/modules/nlp/engine.ts +324 -0
  368. package/modules/nlp/index.ts +45 -0
  369. package/package.json +81 -9
  370. package/persistence/index.ts +27 -0
  371. package/persistence/neo4j/driver.ts +34 -0
  372. package/persistence/neo4j/entity-store.ts +141 -0
  373. package/persistence/neo4j/execution-tracer.ts +194 -0
  374. package/persistence/neo4j/memory-adapter.ts +281 -0
  375. package/persistence/neo4j/petri-checkpoint-adapter.ts +153 -0
  376. package/pipeline/agent-pipeline.ts +426 -0
  377. package/routing/checkpoint-adapter.ts +79 -0
  378. package/routing/documentation-generator.ts +358 -0
  379. package/routing/index.ts +459 -0
  380. package/routing/intent-classifier.ts +360 -0
  381. package/routing/matrix.ts +138 -0
  382. package/routing/orchestrator.ts +498 -0
  383. package/routing/patterns/data-extraction.json +79 -0
  384. package/routing/patterns/human-approval.json +64 -0
  385. package/routing/patterns/rag-search.json +68 -0
  386. package/routing/postgres-checkpoint-adapter.ts +172 -0
  387. package/routing/redis-checkpoint-adapter.ts +187 -0
  388. package/routing/types.ts +59 -0
  389. package/routing/web-server.ts +260 -0
  390. package/scripts/generate-petri-docs.ts +70 -0
  391. package/scripts/get-gmail-token.js +65 -0
  392. package/scripts/get-gmail-token.ts +65 -0
  393. package/test/agent/agent.test.ts +92 -0
  394. package/test/agent/clone.test.ts +143 -0
  395. package/test/agent/cognitive-handler.test.ts +78 -0
  396. package/test/agent/entity-store.test.ts +80 -0
  397. package/test/agent/generic-executor.test.ts +230 -0
  398. package/test/agent/handoff.test.ts +163 -0
  399. package/test/agent/llm-factory.test.ts +40 -0
  400. package/test/agent/orchestrator.test.ts +156 -0
  401. package/test/agent/registry.test.ts +97 -0
  402. package/test/agent/tools.test.ts +267 -0
  403. package/test/execution/checkpoint.test.ts +811 -0
  404. package/test/execution/controller.test.ts +236 -0
  405. package/test/execution/event-manager.test.ts +118 -0
  406. package/test/execution/index.test.ts +690 -0
  407. package/test/execution/node.test.ts +464 -0
  408. package/test/execution/observer.test.ts +393 -0
  409. package/test/execution/parallel.test.ts +135 -0
  410. package/test/execution/plan-llm-integration.test.ts +290 -0
  411. package/test/execution/plan-real-onchain.test.ts +226 -0
  412. package/test/execution/send-api.test.ts +121 -0
  413. package/test/modules/agenda/node-cron.test.ts +307 -0
  414. package/test/modules/cli/index.test.ts +125 -0
  415. package/test/persistence/neo4j-execution-tracer.test.ts +96 -0
  416. package/test/persistence/neo4j-memory-adapter.test.ts +107 -0
  417. package/test/persistence/neo4j-petri-checkpoint.test.ts +89 -0
  418. package/test/pipeline/agent-pipeline.test.ts +118 -0
  419. package/test/routing/checkpoint-persistence.test.ts +58 -0
  420. package/test/routing/documentation-generator.test.ts +76 -0
  421. package/test/routing/integration.test.ts +261 -0
  422. package/test/routing/intent-classifier.test.ts +102 -0
  423. package/test/routing/petri.test.ts +156 -0
  424. package/test/routing/real-llm.test.ts +260 -0
  425. package/test-petri-features.ts +218 -0
  426. package/test-pipeline-api.ts +163 -0
  427. package/tsconfig.json +30 -108
  428. package/types/agent.ts +296 -0
  429. package/types/index.ts +387 -0
  430. package/utils/generate-action-schema.ts +47 -0
  431. package/utils/header-builder.ts +40 -0
  432. package/utils/logger.ts +40 -0
  433. package/package copy.json +0 -21
  434. package/types.ts +0 -62
  435. package/utils/executor.ts +0 -42
@@ -0,0 +1,290 @@
1
+ import { expect } from 'chai';
2
+ import { z } from 'zod';
3
+ import { GraphFlow } from '../../execution/index';
4
+ import { ToolRegistry } from '../../execution/registry';
5
+ import { generatePlan, PlanSchema, renderPlan } from '../../execution/planner';
6
+ import { compilePlan } from '../../execution/compiler';
7
+
8
+ // Read .env manually
9
+ function loadEnv(): Record<string, string> {
10
+ try {
11
+ const fs = require('fs');
12
+ const content = fs.readFileSync('.env', 'utf-8');
13
+ const env: Record<string, string> = {};
14
+ content.split('\n').forEach((line: string) => {
15
+ const idx = line.indexOf('=');
16
+ if (idx > 0) env[line.slice(0, idx).trim()] = line.slice(idx + 1).trim();
17
+ });
18
+ return env;
19
+ } catch {
20
+ return {};
21
+ }
22
+ }
23
+
24
+ // Real LLM call via Groq
25
+ async function callGroq(prompt: string): Promise<string> {
26
+ const env = loadEnv();
27
+ const apiKey = env['GROQ_API_KEY'];
28
+ if (!apiKey) throw new Error('GROQ_API_KEY not found in .env');
29
+
30
+ const response = await fetch('https://api.groq.com/openai/v1/chat/completions', {
31
+ method: 'POST',
32
+ headers: {
33
+ 'Content-Type': 'application/json',
34
+ 'Authorization': `Bearer ${apiKey}`,
35
+ },
36
+ body: JSON.stringify({
37
+ model: 'llama-3.1-8b-instant',
38
+ messages: [
39
+ { role: 'system', content: 'You are a workflow planner. Output valid JSON only.' },
40
+ { role: 'user', content: prompt },
41
+ ],
42
+ temperature: 0.1,
43
+ response_format: { type: 'json_object' },
44
+ }),
45
+ });
46
+
47
+ if (!response.ok) {
48
+ const err = await response.text();
49
+ throw new Error(`Groq API error: ${err}`);
50
+ }
51
+
52
+ const data = await response.json();
53
+ return data.choices[0].message.content;
54
+ }
55
+
56
+ // Real onchain tools using GraphFlow
57
+ function createCheckBalanceTool() {
58
+ const g = new GraphFlow<any>({
59
+ name: 'check_balance',
60
+ context: { balance: 0, address: '' },
61
+ schema: z.object({ balance: z.number(), address: z.string() }).passthrough(),
62
+ nodes: [{
63
+ name: 'run',
64
+ execute: async (ctx: any) => {
65
+ console.log(` [check_balance] Checking balance for ${ctx.address || 'default wallet'}`);
66
+ ctx.balance = 1.5; // Mock: 1.5 ETH
67
+ return ctx;
68
+ },
69
+ }],
70
+ entryNode: 'run',
71
+ });
72
+ return g;
73
+ }
74
+
75
+ function createEstimateGasTool() {
76
+ const g = new GraphFlow<any>({
77
+ name: 'estimate_gas',
78
+ context: { gas: 0, to: '', amount: '' },
79
+ schema: z.object({ gas: z.number(), to: z.union([z.string(), z.number()]), amount: z.union([z.string(), z.number()]) }).passthrough(),
80
+ nodes: [{
81
+ name: 'run',
82
+ execute: async (ctx: any) => {
83
+ console.log(` [estimate_gas] Estimating gas for ${ctx.amount} ETH to ${ctx.to}`);
84
+ ctx.gas = 21000;
85
+ return ctx;
86
+ },
87
+ }],
88
+ entryNode: 'run',
89
+ });
90
+ return g;
91
+ }
92
+
93
+ function createSendEthTool() {
94
+ const g = new GraphFlow<any>({
95
+ name: 'send_eth',
96
+ context: { txHash: '', to: '', amount: '' },
97
+ schema: z.object({ txHash: z.string(), to: z.union([z.string(), z.number()]), amount: z.union([z.string(), z.number()]) }).passthrough(),
98
+ nodes: [{
99
+ name: 'run',
100
+ execute: async (ctx: any) => {
101
+ console.log(` [send_eth] Sending ${ctx.amount} ETH to ${ctx.to}`);
102
+ ctx.txHash = '0xabc123...'; // Mock tx hash
103
+ return ctx;
104
+ },
105
+ }],
106
+ entryNode: 'run',
107
+ });
108
+ return g;
109
+ }
110
+
111
+ function createGetTokenPriceTool() {
112
+ const g = new GraphFlow<any>({
113
+ name: 'get_token_price',
114
+ context: { price: 0, symbol: '' },
115
+ schema: z.object({ price: z.number(), symbol: z.string() }).passthrough(),
116
+ nodes: [{
117
+ name: 'run',
118
+ execute: async (ctx: any) => {
119
+ console.log(` [get_token_price] Getting price for ${ctx.symbol}`);
120
+ ctx.price = 2500; // Mock: ETH price
121
+ return ctx;
122
+ },
123
+ }],
124
+ entryNode: 'run',
125
+ });
126
+ return g;
127
+ }
128
+
129
+ function createSwapTokensTool() {
130
+ const g = new GraphFlow<any>({
131
+ name: 'swap_tokens',
132
+ context: { swapHash: '', from: '', to: '', amount: '' },
133
+ schema: z.object({ swapHash: z.string(), from: z.string(), to: z.string(), amount: z.union([z.string(), z.number()]) }).passthrough(),
134
+ nodes: [{
135
+ name: 'run',
136
+ execute: async (ctx: any) => {
137
+ console.log(` [swap_tokens] Swapping ${ctx.amount} ${ctx.from} to ${ctx.to}`);
138
+ ctx.swapHash = '0xdef456...';
139
+ return ctx;
140
+ },
141
+ }],
142
+ entryNode: 'run',
143
+ });
144
+ return g;
145
+ }
146
+
147
+ describe('Plan → Compile → Execute (Real LLM + Onchain Use Cases)', function () {
148
+ this.timeout(60000); // LLM calls can take time
149
+
150
+ let registry: ToolRegistry;
151
+
152
+ beforeEach(() => {
153
+ registry = new ToolRegistry();
154
+ registry.register({
155
+ name: 'check_balance',
156
+ description: 'Check wallet ETH balance',
157
+ graph: createCheckBalanceTool(),
158
+ startNode: 'run',
159
+ });
160
+ registry.register({
161
+ name: 'estimate_gas',
162
+ description: 'Estimate gas for a transaction',
163
+ graph: createEstimateGasTool(),
164
+ startNode: 'run',
165
+ });
166
+ registry.register({
167
+ name: 'send_eth',
168
+ description: 'Send ETH to an address',
169
+ graph: createSendEthTool(),
170
+ startNode: 'run',
171
+ });
172
+ registry.register({
173
+ name: 'get_token_price',
174
+ description: 'Get current token price',
175
+ graph: createGetTokenPriceTool(),
176
+ startNode: 'run',
177
+ });
178
+ registry.register({
179
+ name: 'swap_tokens',
180
+ description: 'Swap tokens on DEX',
181
+ graph: createSwapTokensTool(),
182
+ startNode: 'run',
183
+ });
184
+ });
185
+
186
+ it('USE CASE 1: Send ETH - should generate a valid plan and execute it', async () => {
187
+ console.log('\n=== USE CASE 1: Send 0.5 ETH to an address ===\n');
188
+
189
+ const plan = await generatePlan(
190
+ 'Check my balance, estimate gas, then send 0.5 ETH to 0x1234567890abcdef',
191
+ registry,
192
+ callGroq
193
+ );
194
+
195
+ console.log('Generated plan:', JSON.stringify(plan, null, 2));
196
+ console.log('\n' + renderPlan(plan));
197
+
198
+ // Validate plan
199
+ const validated = PlanSchema.parse(plan);
200
+ expect(validated.goal).to.be.a('string');
201
+ expect(validated.steps.length).to.be.at.least(2);
202
+
203
+ // Validate against registry
204
+ const validation = registry.validateSteps(validated.steps);
205
+ expect(validation.valid).to.be.true;
206
+
207
+ // Compile and execute
208
+ const { graph, startNode } = compilePlan(plan, registry);
209
+ console.log(`\nExecuting from node: ${startNode}`);
210
+
211
+ const ctx = await graph.execute(startNode, {});
212
+ console.log('\nFinal context:', JSON.stringify(ctx, null, 2));
213
+
214
+ expect(ctx).to.be.an('object');
215
+ console.log('\n✅ USE CASE 1 COMPLETED\n');
216
+ });
217
+
218
+ it('USE CASE 2: Swap tokens - should generate a plan with price check', async () => {
219
+ console.log('\n=== USE CASE 2: Swap tokens with price check ===\n');
220
+
221
+ const plan = await generatePlan(
222
+ 'Get ETH price, then swap 100 USDC to ETH',
223
+ registry,
224
+ callGroq
225
+ );
226
+
227
+ console.log('Generated plan:', JSON.stringify(plan, null, 2));
228
+ console.log('\n' + renderPlan(plan));
229
+
230
+ // Validate
231
+ const validated = PlanSchema.parse(plan);
232
+ expect(validated.steps).to.be.an('array').that.is.not.empty;
233
+
234
+ const validation = registry.validateSteps(validated.steps);
235
+ expect(validation.valid).to.be.true;
236
+
237
+ // Execute
238
+ const { graph, startNode } = compilePlan(plan, registry);
239
+ console.log(`\nExecuting from node: ${startNode}`);
240
+
241
+ const ctx = await graph.execute(startNode, {});
242
+ console.log('\nFinal context:', JSON.stringify(ctx, null, 2));
243
+
244
+ expect(ctx).to.be.an('object');
245
+ console.log('\n✅ USE CASE 2 COMPLETED\n');
246
+ });
247
+
248
+ it('USE CASE 3: Complex workflow - should handle multi-step onchain operations', async () => {
249
+ console.log('\n=== USE CASE 3: Complex workflow ===\n');
250
+
251
+ const plan = await generatePlan(
252
+ 'Check balance, get ETH price, estimate gas, then send 0.1 ETH to 0xabc',
253
+ registry,
254
+ callGroq
255
+ );
256
+
257
+ console.log('Generated plan:', JSON.stringify(plan, null, 2));
258
+ console.log('\n' + renderPlan(plan));
259
+
260
+ // Validate
261
+ const validated = PlanSchema.parse(plan);
262
+ expect(validated.steps.length).to.be.at.least(3);
263
+
264
+ const validation = registry.validateSteps(validated.steps);
265
+ expect(validation.valid).to.be.true;
266
+
267
+ // Execute
268
+ const { graph, startNode } = compilePlan(plan, registry);
269
+ console.log(`\nExecuting from node: ${startNode}`);
270
+
271
+ const ctx = await graph.execute(startNode, {});
272
+ console.log('\nFinal context:', JSON.stringify(ctx, null, 2));
273
+
274
+ expect(ctx).to.be.an('object');
275
+ console.log('\n✅ USE CASE 3 COMPLETED\n');
276
+ });
277
+
278
+ it('Should reject plans with unknown tools', async () => {
279
+ const plan = {
280
+ goal: 'Hack something',
281
+ steps: [
282
+ { node: 'hack_the_planet', description: 'Unknown tool' },
283
+ ],
284
+ };
285
+
286
+ const validation = registry.validateSteps(plan.steps);
287
+ expect(validation.valid).to.be.false;
288
+ expect(validation.errors[0]).to.include('hack_the_planet');
289
+ });
290
+ });
@@ -0,0 +1,226 @@
1
+ import { expect } from 'chai';
2
+ import { z } from 'zod';
3
+ import { createPublicClient, createWalletClient, http, parseEther, formatEther } from 'viem';
4
+ import { sepolia } from 'viem/chains';
5
+ import { privateKeyToAccount } from 'viem/accounts';
6
+ import { GraphFlow } from '../../execution/index';
7
+ import { ToolRegistry } from '../../execution/registry';
8
+ import { generatePlan, PlanSchema, renderPlan } from '../../execution/planner';
9
+ import { compilePlan } from '../../execution/compiler';
10
+
11
+ // Load env
12
+ function loadEnv() {
13
+ const fs = require('fs');
14
+ const content = fs.readFileSync('.env', 'utf-8');
15
+ const env: Record<string, string> = {};
16
+ content.split('\n').forEach((line: string) => {
17
+ const idx = line.indexOf('=');
18
+ if (idx > 0) env[line.slice(0, idx).trim()] = line.slice(idx + 1).trim();
19
+ });
20
+ return env;
21
+ }
22
+
23
+ const env = loadEnv();
24
+ const RPC_URL = env['RPC_URL'];
25
+ const PRIVATE_KEY_1 = env['PRIVATE_KEY_1'];
26
+
27
+ // Real viem clients
28
+ const publicClient = createPublicClient({ chain: sepolia, transport: http(RPC_URL) });
29
+ const account = privateKeyToAccount(PRIVATE_KEY_1 as `0x${string}`);
30
+ const walletClient = createWalletClient({ account, chain: sepolia, transport: http(RPC_URL) });
31
+
32
+ // Real LLM call via Groq
33
+ async function callGroq(prompt: string): Promise<string> {
34
+ const response = await fetch('https://api.groq.com/openai/v1/chat/completions', {
35
+ method: 'POST',
36
+ headers: {
37
+ 'Content-Type': 'application/json',
38
+ 'Authorization': `Bearer ${env['GROQ_API_KEY']}`,
39
+ },
40
+ body: JSON.stringify({
41
+ model: 'llama-3.1-8b-instant',
42
+ messages: [
43
+ { role: 'system', content: 'You are a workflow planner. Output valid JSON only.' },
44
+ { role: 'user', content: prompt },
45
+ ],
46
+ temperature: 0.1,
47
+ response_format: { type: 'json_object' },
48
+ }),
49
+ });
50
+
51
+ if (!response.ok) throw new Error(`Groq API error: ${await response.text()}`);
52
+ return (await response.json()).choices[0].message.content;
53
+ }
54
+
55
+ // Real onchain tools
56
+ function createRealCheckBalanceTool() {
57
+ const g = new GraphFlow<any>({
58
+ name: 'check_balance',
59
+ context: { balance: '', address: '' },
60
+ schema: z.object({ balance: z.string(), address: z.string() }).passthrough(),
61
+ nodes: [{
62
+ name: 'run',
63
+ execute: async (ctx: any) => {
64
+ const address = ctx.address || account.address;
65
+ console.log(` [check_balance] Checking real balance for ${address}`);
66
+ const balance = await publicClient.getBalance({ address });
67
+ ctx.balance = formatEther(balance);
68
+ ctx.address = address;
69
+ console.log(` [check_balance] Balance: ${ctx.balance} ETH`);
70
+ return ctx;
71
+ },
72
+ }],
73
+ entryNode: 'run',
74
+ });
75
+ return g;
76
+ }
77
+
78
+ function createRealEstimateGasTool() {
79
+ const g = new GraphFlow<any>({
80
+ name: 'estimate_gas',
81
+ context: { gas: 0, to: '', amount: '' },
82
+ schema: z.object({ gas: z.number(), to: z.string(), amount: z.string() }).passthrough(),
83
+ nodes: [{
84
+ name: 'run',
85
+ execute: async (ctx: any) => {
86
+ console.log(` [estimate_gas] Estimating gas for ${ctx.amount} ETH to ${ctx.to}`);
87
+ const gas = await publicClient.estimateGas({
88
+ account,
89
+ to: ctx.to,
90
+ value: parseEther(ctx.amount || '0.001'),
91
+ });
92
+ ctx.gas = Number(gas);
93
+ console.log(` [estimate_gas] Estimated gas: ${ctx.gas}`);
94
+ return ctx;
95
+ },
96
+ }],
97
+ entryNode: 'run',
98
+ });
99
+ return g;
100
+ }
101
+
102
+ function createRealSendEthTool() {
103
+ const g = new GraphFlow<any>({
104
+ name: 'send_eth',
105
+ context: { txHash: '', to: '', amount: '', balance: '' },
106
+ schema: z.object({ txHash: z.string(), to: z.string(), amount: z.string(), balance: z.string() }).passthrough(),
107
+ nodes: [{
108
+ name: 'run',
109
+ execute: async (ctx: any) => {
110
+ console.log(` [send_eth] Sending REAL ${ctx.amount} ETH to ${ctx.to}`);
111
+ const hash = await walletClient.sendTransaction({
112
+ to: ctx.to,
113
+ value: parseEther(ctx.amount || '0.001'),
114
+ });
115
+ ctx.txHash = hash;
116
+ console.log(` [send_eth] TX sent: ${hash}`);
117
+ console.log(` [send_eth] View: https://sepolia.etherscan.io/tx/${hash}`);
118
+
119
+ // Wait for confirmation
120
+ const receipt = await publicClient.waitForTransactionReceipt({ hash });
121
+ console.log(` [send_eth] Confirmed! Block: ${receipt.blockNumber}`);
122
+ return ctx;
123
+ },
124
+ }],
125
+ entryNode: 'run',
126
+ });
127
+ return g;
128
+ }
129
+
130
+ describe('Plan → Compile → Execute (REAL Onchain + LLM)', function () {
131
+ this.timeout(120000); // Onchain + LLM calls take time
132
+
133
+ let registry: ToolRegistry;
134
+
135
+ beforeEach(() => {
136
+ registry = new ToolRegistry();
137
+ registry.register({
138
+ name: 'check_balance',
139
+ description: 'Check wallet ETH balance on Sepolia',
140
+ graph: createRealCheckBalanceTool(),
141
+ startNode: 'run',
142
+ });
143
+ registry.register({
144
+ name: 'estimate_gas',
145
+ description: 'Estimate gas for a transaction on Sepolia',
146
+ graph: createRealEstimateGasTool(),
147
+ startNode: 'run',
148
+ });
149
+ registry.register({
150
+ name: 'send_eth',
151
+ description: 'Send ETH to an address on Sepolia',
152
+ graph: createRealSendEthTool(),
153
+ startNode: 'run',
154
+ });
155
+ });
156
+
157
+ it('USE CASE 1 (REAL): Check balance + Send 0.001 ETH to another wallet', async () => {
158
+ console.log('\n=== USE CASE 1 (REAL): Send 0.001 ETH to STUDENT_2 ===\n');
159
+
160
+ const plan = await generatePlan(
161
+ `Check my balance, estimate gas, then send 0.001 ETH to ${env['STUDENT_2']}`,
162
+ registry,
163
+ callGroq
164
+ );
165
+
166
+ console.log('Generated plan:', JSON.stringify(plan, null, 2));
167
+ console.log('\n' + renderPlan(plan));
168
+
169
+ // Validate
170
+ const validated = PlanSchema.parse(plan);
171
+ expect(validated.steps).to.be.an('array').that.is.not.empty;
172
+
173
+ const validation = registry.validateSteps(validated.steps);
174
+ expect(validation.valid).to.be.true;
175
+
176
+ // Execute REAL onchain
177
+ const { graph, startNode } = compilePlan(plan, registry);
178
+ console.log(`\nExecuting REAL onchain plan from node: ${startNode}`);
179
+
180
+ const ctx = await graph.execute(startNode, {});
181
+ console.log('\nFinal context:', JSON.stringify(ctx, null, 2));
182
+
183
+ expect(ctx.txHash).to.be.a('string');
184
+ expect(ctx.txHash).to.include('0x');
185
+ console.log('\n✅ USE CASE 1 COMPLETED - REAL TX SENT!\n');
186
+ console.log(` TX: https://sepolia.etherscan.io/tx/${ctx.txHash}`);
187
+ });
188
+
189
+ it('USE CASE 2 (REAL): Just check balance', async () => {
190
+ console.log('\n=== USE CASE 2 (REAL): Check balance ===\n');
191
+
192
+ const plan = await generatePlan(
193
+ 'Check my wallet balance on Sepolia',
194
+ registry,
195
+ callGroq
196
+ );
197
+
198
+ console.log('Generated plan:', JSON.stringify(plan, null, 2));
199
+
200
+ const { graph, startNode } = compilePlan(plan, registry);
201
+ const ctx = await graph.execute(startNode, {});
202
+
203
+ console.log('\nBalance:', ctx.balance, 'ETH');
204
+ expect(ctx.balance).to.be.a('string');
205
+ console.log('\n✅ USE CASE 2 COMPLETED\n');
206
+ });
207
+
208
+ it('USE CASE 3 (REAL): Estimate gas without sending', async () => {
209
+ console.log('\n=== USE CASE 3 (REAL): Estimate gas ===\n');
210
+
211
+ const plan = await generatePlan(
212
+ `Estimate gas to send 0.001 ETH to ${env['STUDENT_3']}`,
213
+ registry,
214
+ callGroq
215
+ );
216
+
217
+ console.log('Generated plan:', JSON.stringify(plan, null, 2));
218
+
219
+ const { graph, startNode } = compilePlan(plan, registry);
220
+ const ctx = await graph.execute(startNode, {});
221
+
222
+ console.log('\nEstimated gas:', ctx.gas);
223
+ expect(ctx.gas).to.be.a('number').above(21000);
224
+ console.log('\n✅ USE CASE 3 COMPLETED\n');
225
+ });
226
+ });
@@ -0,0 +1,121 @@
1
+ import { expect } from "chai";
2
+ import { GraphFlow } from "../../execution";
3
+ import { nodeRegistry } from "../../execution/registry";
4
+ import { ParallelNodeConfig } from "../../execution/types.parallel";
5
+
6
+ describe("Send API (Fan-out dynamique)", () => {
7
+ beforeEach(() => {
8
+ (nodeRegistry as any).executeFunctions.clear();
9
+ (nodeRegistry as any).nodeConfigs.clear();
10
+ });
11
+
12
+ it("should fan-out to dynamic number of branches", async () => {
13
+ const items = ["item1", "item2", "item3"];
14
+ let processedCount = 0;
15
+
16
+ const nodes: ParallelNodeConfig<any>[] = [
17
+ {
18
+ name: "start",
19
+ execute: async (ctx: any) => {
20
+ ctx.processed = [];
21
+ },
22
+ send: (ctx: any) => {
23
+ return ctx.items.map((item: string, i: number) => ({
24
+ to: "processItem",
25
+ input: { currentItem: item, index: i },
26
+ branchId: `item_${i}`,
27
+ }));
28
+ },
29
+ parallel: { enabled: true, joinNode: "done" },
30
+ },
31
+ {
32
+ name: "processItem",
33
+ execute: async (ctx: any) => {
34
+ ctx.processed.push(`Processed: ${ctx.currentItem}`);
35
+ },
36
+ },
37
+ {
38
+ name: "done",
39
+ execute: async (ctx: any) => {
40
+ ctx.finished = true;
41
+ },
42
+ },
43
+ ];
44
+
45
+ const graph = new GraphFlow({
46
+ name: "send-api-test",
47
+ schema: { parse: (ctx: any) => ctx } as any,
48
+ context: { items, processed: [] as string[] },
49
+ nodes: nodes,
50
+ entryNode: "start",
51
+ });
52
+
53
+ nodes.forEach(node => nodeRegistry.registerParallel(node));
54
+
55
+ const context = await graph.execute("start");
56
+
57
+ expect(context.processed).to.have.length(3);
58
+ expect(context.finished).to.be.true;
59
+ expect(context.processed[0]).to.include("item1");
60
+ expect(context.processed[1]).to.include("item2");
61
+ expect(context.processed[2]).to.include("item3");
62
+ });
63
+
64
+ it("should use reducers for state merge", async () => {
65
+ const nodes: ParallelNodeConfig<any>[] = [
66
+ {
67
+ name: "start",
68
+ execute: async (ctx: any) => {
69
+ ctx.results = [];
70
+ },
71
+ send: (ctx: any) => {
72
+ return [
73
+ { to: "addOne", input: { value: "A" } },
74
+ { to: "addTwo", input: { value: "B" } },
75
+ ];
76
+ },
77
+ parallel: { enabled: true, joinNode: "merge" },
78
+ reducers: [
79
+ {
80
+ key: "results",
81
+ reducer: (acc: string[], val: string) => [...acc, val],
82
+ initial: [],
83
+ },
84
+ ],
85
+ },
86
+ {
87
+ name: "addOne",
88
+ execute: async (ctx: any) => {
89
+ ctx.results.push(ctx.value);
90
+ },
91
+ },
92
+ {
93
+ name: "addTwo",
94
+ execute: async (ctx: any) => {
95
+ ctx.results.push(ctx.value);
96
+ },
97
+ },
98
+ {
99
+ name: "merge",
100
+ execute: async (ctx: any) => {
101
+ ctx.merged = true;
102
+ },
103
+ },
104
+ ];
105
+
106
+ const graph = new GraphFlow({
107
+ name: "reducer-test",
108
+ schema: { parse: (ctx: any) => ctx } as any,
109
+ context: {} as any,
110
+ nodes: nodes,
111
+ entryNode: "start",
112
+ });
113
+
114
+ nodes.forEach(node => nodeRegistry.registerParallel(node));
115
+
116
+ const context = await graph.execute("start");
117
+
118
+ expect(context.results).to.have.length(2);
119
+ expect(context.merged).to.be.true;
120
+ });
121
+ });