@falai/agent 1.2.7 → 2.0.0

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 (508) hide show
  1. package/README.md +40 -886
  2. package/dist/adapters/MemoryAdapter.js +2 -2
  3. package/dist/adapters/MemoryAdapter.js.map +1 -1
  4. package/dist/adapters/MongoAdapter.js +2 -2
  5. package/dist/adapters/MongoAdapter.js.map +1 -1
  6. package/dist/adapters/OpenSearchAdapter.d.ts.map +1 -1
  7. package/dist/adapters/OpenSearchAdapter.js +9 -7
  8. package/dist/adapters/OpenSearchAdapter.js.map +1 -1
  9. package/dist/adapters/PostgreSQLAdapter.d.ts +14 -0
  10. package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  11. package/dist/adapters/PostgreSQLAdapter.js +25 -9
  12. package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
  13. package/dist/adapters/PrismaAdapter.js +5 -5
  14. package/dist/adapters/PrismaAdapter.js.map +1 -1
  15. package/dist/adapters/RedisAdapter.js +2 -2
  16. package/dist/adapters/RedisAdapter.js.map +1 -1
  17. package/dist/adapters/SQLiteAdapter.d.ts +17 -0
  18. package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
  19. package/dist/adapters/SQLiteAdapter.js +30 -11
  20. package/dist/adapters/SQLiteAdapter.js.map +1 -1
  21. package/dist/cjs/adapters/MemoryAdapter.js +2 -2
  22. package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
  23. package/dist/cjs/adapters/MongoAdapter.js +2 -2
  24. package/dist/cjs/adapters/MongoAdapter.js.map +1 -1
  25. package/dist/cjs/adapters/OpenSearchAdapter.d.ts.map +1 -1
  26. package/dist/cjs/adapters/OpenSearchAdapter.js +9 -7
  27. package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -1
  28. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts +14 -0
  29. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  30. package/dist/cjs/adapters/PostgreSQLAdapter.js +25 -9
  31. package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
  32. package/dist/cjs/adapters/PrismaAdapter.js +5 -5
  33. package/dist/cjs/adapters/PrismaAdapter.js.map +1 -1
  34. package/dist/cjs/adapters/RedisAdapter.js +2 -2
  35. package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
  36. package/dist/cjs/adapters/SQLiteAdapter.d.ts +17 -0
  37. package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
  38. package/dist/cjs/adapters/SQLiteAdapter.js +30 -11
  39. package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -1
  40. package/dist/cjs/constants/index.d.ts +0 -9
  41. package/dist/cjs/constants/index.d.ts.map +1 -1
  42. package/dist/cjs/constants/index.js +2 -11
  43. package/dist/cjs/constants/index.js.map +1 -1
  44. package/dist/cjs/core/Agent.d.ts +119 -153
  45. package/dist/cjs/core/Agent.d.ts.map +1 -1
  46. package/dist/cjs/core/Agent.js +471 -324
  47. package/dist/cjs/core/Agent.js.map +1 -1
  48. package/dist/cjs/core/AutoChainExecutor.d.ts +107 -0
  49. package/dist/cjs/core/AutoChainExecutor.d.ts.map +1 -0
  50. package/dist/cjs/core/AutoChainExecutor.js +297 -0
  51. package/dist/cjs/core/AutoChainExecutor.js.map +1 -0
  52. package/dist/cjs/core/BranchEvaluator.d.ts +54 -0
  53. package/dist/cjs/core/BranchEvaluator.d.ts.map +1 -0
  54. package/dist/cjs/core/BranchEvaluator.js +130 -0
  55. package/dist/cjs/core/BranchEvaluator.js.map +1 -0
  56. package/dist/cjs/core/DirectiveBus.d.ts +88 -0
  57. package/dist/cjs/core/DirectiveBus.d.ts.map +1 -0
  58. package/dist/cjs/core/DirectiveBus.js +196 -0
  59. package/dist/cjs/core/DirectiveBus.js.map +1 -0
  60. package/dist/cjs/core/DirectiveChainTracker.d.ts +49 -0
  61. package/dist/cjs/core/DirectiveChainTracker.d.ts.map +1 -0
  62. package/dist/cjs/core/DirectiveChainTracker.js +121 -0
  63. package/dist/cjs/core/DirectiveChainTracker.js.map +1 -0
  64. package/dist/cjs/core/Flow.d.ts +186 -0
  65. package/dist/cjs/core/Flow.d.ts.map +1 -0
  66. package/dist/cjs/core/Flow.js +550 -0
  67. package/dist/cjs/core/Flow.js.map +1 -0
  68. package/dist/cjs/core/FlowRouter.d.ts +182 -0
  69. package/dist/cjs/core/FlowRouter.d.ts.map +1 -0
  70. package/dist/cjs/core/{RoutingEngine.js → FlowRouter.js} +323 -306
  71. package/dist/cjs/core/FlowRouter.js.map +1 -0
  72. package/dist/cjs/core/PersistenceManager.d.ts +2 -2
  73. package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
  74. package/dist/cjs/core/PersistenceManager.js +7 -7
  75. package/dist/cjs/core/PersistenceManager.js.map +1 -1
  76. package/dist/cjs/core/PromptComposer.d.ts +21 -8
  77. package/dist/cjs/core/PromptComposer.d.ts.map +1 -1
  78. package/dist/cjs/core/PromptComposer.js +182 -105
  79. package/dist/cjs/core/PromptComposer.js.map +1 -1
  80. package/dist/cjs/core/PromptSectionCache.d.ts +1 -1
  81. package/dist/cjs/core/PromptSectionCache.js +1 -1
  82. package/dist/cjs/core/ResponseEngine.d.ts +18 -8
  83. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
  84. package/dist/cjs/core/ResponseEngine.js +38 -36
  85. package/dist/cjs/core/ResponseEngine.js.map +1 -1
  86. package/dist/cjs/core/ResponseModal.d.ts +73 -56
  87. package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
  88. package/dist/cjs/core/ResponseModal.js +1196 -1015
  89. package/dist/cjs/core/ResponseModal.js.map +1 -1
  90. package/dist/cjs/core/ResponsePipeline.d.ts +124 -26
  91. package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -1
  92. package/dist/cjs/core/ResponsePipeline.js +524 -134
  93. package/dist/cjs/core/ResponsePipeline.js.map +1 -1
  94. package/dist/cjs/core/SignalEvaluator.d.ts +86 -0
  95. package/dist/cjs/core/SignalEvaluator.d.ts.map +1 -0
  96. package/dist/cjs/core/SignalEvaluator.js +333 -0
  97. package/dist/cjs/core/SignalEvaluator.js.map +1 -0
  98. package/dist/cjs/core/SignalProcessor.d.ts +152 -0
  99. package/dist/cjs/core/SignalProcessor.d.ts.map +1 -0
  100. package/dist/cjs/core/SignalProcessor.js +562 -0
  101. package/dist/cjs/core/SignalProcessor.js.map +1 -0
  102. package/dist/cjs/core/Step.d.ts +43 -32
  103. package/dist/cjs/core/Step.d.ts.map +1 -1
  104. package/dist/cjs/core/Step.js +221 -126
  105. package/dist/cjs/core/Step.js.map +1 -1
  106. package/dist/cjs/core/StreamingToolExecutor.d.ts +2 -2
  107. package/dist/cjs/core/StreamingToolExecutor.d.ts.map +1 -1
  108. package/dist/cjs/core/StreamingToolExecutor.js.map +1 -1
  109. package/dist/cjs/core/ToolManager.d.ts +44 -13
  110. package/dist/cjs/core/ToolManager.d.ts.map +1 -1
  111. package/dist/cjs/core/ToolManager.js +174 -91
  112. package/dist/cjs/core/ToolManager.js.map +1 -1
  113. package/dist/cjs/core/createAgent.d.ts +35 -0
  114. package/dist/cjs/core/createAgent.d.ts.map +1 -0
  115. package/dist/cjs/core/createAgent.js +39 -0
  116. package/dist/cjs/core/createAgent.js.map +1 -0
  117. package/dist/cjs/core/flow-namespace.d.ts +49 -0
  118. package/dist/cjs/core/flow-namespace.d.ts.map +1 -0
  119. package/dist/cjs/core/flow-namespace.js +171 -0
  120. package/dist/cjs/core/flow-namespace.js.map +1 -0
  121. package/dist/cjs/index.d.ts +11 -14
  122. package/dist/cjs/index.d.ts.map +1 -1
  123. package/dist/cjs/index.js +18 -22
  124. package/dist/cjs/index.js.map +1 -1
  125. package/dist/cjs/providers/GeminiProvider.d.ts +3 -3
  126. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  127. package/dist/cjs/providers/GeminiProvider.js +16 -14
  128. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  129. package/dist/cjs/types/agent.d.ts +183 -54
  130. package/dist/cjs/types/agent.d.ts.map +1 -1
  131. package/dist/cjs/types/agent.js +0 -6
  132. package/dist/cjs/types/agent.js.map +1 -1
  133. package/dist/cjs/types/ai.d.ts +3 -3
  134. package/dist/cjs/types/ai.d.ts.map +1 -1
  135. package/dist/cjs/types/errors.d.ts +15 -0
  136. package/dist/cjs/types/errors.d.ts.map +1 -0
  137. package/dist/cjs/types/errors.js +22 -0
  138. package/dist/cjs/types/errors.js.map +1 -0
  139. package/dist/cjs/types/flow.d.ts +513 -0
  140. package/dist/cjs/types/flow.d.ts.map +1 -0
  141. package/dist/cjs/types/{route.js → flow.js} +2 -2
  142. package/dist/cjs/types/flow.js.map +1 -0
  143. package/dist/cjs/types/index.d.ts +7 -6
  144. package/dist/cjs/types/index.d.ts.map +1 -1
  145. package/dist/cjs/types/index.js +6 -2
  146. package/dist/cjs/types/index.js.map +1 -1
  147. package/dist/cjs/types/persistence.d.ts +11 -7
  148. package/dist/cjs/types/persistence.d.ts.map +1 -1
  149. package/dist/cjs/types/routing.d.ts +1 -1
  150. package/dist/cjs/types/routing.d.ts.map +1 -1
  151. package/dist/cjs/types/session.d.ts +24 -23
  152. package/dist/cjs/types/session.d.ts.map +1 -1
  153. package/dist/cjs/types/signals.d.ts +248 -0
  154. package/dist/cjs/types/signals.d.ts.map +1 -0
  155. package/dist/cjs/types/signals.js +11 -0
  156. package/dist/cjs/types/signals.js.map +1 -0
  157. package/dist/cjs/types/template.d.ts +2 -8
  158. package/dist/cjs/types/template.d.ts.map +1 -1
  159. package/dist/cjs/types/tool.d.ts +36 -29
  160. package/dist/cjs/types/tool.d.ts.map +1 -1
  161. package/dist/cjs/types/tool.js +1 -1
  162. package/dist/cjs/types/tool.js.map +1 -1
  163. package/dist/cjs/utils/condition.d.ts +7 -1
  164. package/dist/cjs/utils/condition.d.ts.map +1 -1
  165. package/dist/cjs/utils/condition.js.map +1 -1
  166. package/dist/cjs/utils/id.d.ts +13 -5
  167. package/dist/cjs/utils/id.d.ts.map +1 -1
  168. package/dist/cjs/utils/id.js +24 -10
  169. package/dist/cjs/utils/id.js.map +1 -1
  170. package/dist/cjs/utils/index.d.ts +2 -2
  171. package/dist/cjs/utils/index.d.ts.map +1 -1
  172. package/dist/cjs/utils/index.js +7 -3
  173. package/dist/cjs/utils/index.js.map +1 -1
  174. package/dist/cjs/utils/session.d.ts +44 -5
  175. package/dist/cjs/utils/session.d.ts.map +1 -1
  176. package/dist/cjs/utils/session.js +197 -38
  177. package/dist/cjs/utils/session.js.map +1 -1
  178. package/dist/constants/index.d.ts +0 -9
  179. package/dist/constants/index.d.ts.map +1 -1
  180. package/dist/constants/index.js +3 -9
  181. package/dist/constants/index.js.map +1 -1
  182. package/dist/core/Agent.d.ts +119 -153
  183. package/dist/core/Agent.d.ts.map +1 -1
  184. package/dist/core/Agent.js +472 -325
  185. package/dist/core/Agent.js.map +1 -1
  186. package/dist/core/AutoChainExecutor.d.ts +107 -0
  187. package/dist/core/AutoChainExecutor.d.ts.map +1 -0
  188. package/dist/core/AutoChainExecutor.js +293 -0
  189. package/dist/core/AutoChainExecutor.js.map +1 -0
  190. package/dist/core/BranchEvaluator.d.ts +54 -0
  191. package/dist/core/BranchEvaluator.d.ts.map +1 -0
  192. package/dist/core/BranchEvaluator.js +126 -0
  193. package/dist/core/BranchEvaluator.js.map +1 -0
  194. package/dist/core/DirectiveBus.d.ts +88 -0
  195. package/dist/core/DirectiveBus.d.ts.map +1 -0
  196. package/dist/core/DirectiveBus.js +192 -0
  197. package/dist/core/DirectiveBus.js.map +1 -0
  198. package/dist/core/DirectiveChainTracker.d.ts +49 -0
  199. package/dist/core/DirectiveChainTracker.d.ts.map +1 -0
  200. package/dist/core/DirectiveChainTracker.js +117 -0
  201. package/dist/core/DirectiveChainTracker.js.map +1 -0
  202. package/dist/core/Flow.d.ts +186 -0
  203. package/dist/core/Flow.d.ts.map +1 -0
  204. package/dist/core/Flow.js +546 -0
  205. package/dist/core/Flow.js.map +1 -0
  206. package/dist/core/FlowRouter.d.ts +182 -0
  207. package/dist/core/FlowRouter.d.ts.map +1 -0
  208. package/dist/core/{RoutingEngine.js → FlowRouter.js} +322 -305
  209. package/dist/core/FlowRouter.js.map +1 -0
  210. package/dist/core/PersistenceManager.d.ts +2 -2
  211. package/dist/core/PersistenceManager.d.ts.map +1 -1
  212. package/dist/core/PersistenceManager.js +7 -7
  213. package/dist/core/PersistenceManager.js.map +1 -1
  214. package/dist/core/PromptComposer.d.ts +21 -8
  215. package/dist/core/PromptComposer.d.ts.map +1 -1
  216. package/dist/core/PromptComposer.js +183 -106
  217. package/dist/core/PromptComposer.js.map +1 -1
  218. package/dist/core/PromptSectionCache.d.ts +1 -1
  219. package/dist/core/PromptSectionCache.js +1 -1
  220. package/dist/core/ResponseEngine.d.ts +18 -8
  221. package/dist/core/ResponseEngine.d.ts.map +1 -1
  222. package/dist/core/ResponseEngine.js +38 -36
  223. package/dist/core/ResponseEngine.js.map +1 -1
  224. package/dist/core/ResponseModal.d.ts +73 -56
  225. package/dist/core/ResponseModal.d.ts.map +1 -1
  226. package/dist/core/ResponseModal.js +1198 -1017
  227. package/dist/core/ResponseModal.js.map +1 -1
  228. package/dist/core/ResponsePipeline.d.ts +124 -26
  229. package/dist/core/ResponsePipeline.d.ts.map +1 -1
  230. package/dist/core/ResponsePipeline.js +524 -135
  231. package/dist/core/ResponsePipeline.js.map +1 -1
  232. package/dist/core/SignalEvaluator.d.ts +86 -0
  233. package/dist/core/SignalEvaluator.d.ts.map +1 -0
  234. package/dist/core/SignalEvaluator.js +326 -0
  235. package/dist/core/SignalEvaluator.js.map +1 -0
  236. package/dist/core/SignalProcessor.d.ts +152 -0
  237. package/dist/core/SignalProcessor.d.ts.map +1 -0
  238. package/dist/core/SignalProcessor.js +555 -0
  239. package/dist/core/SignalProcessor.js.map +1 -0
  240. package/dist/core/Step.d.ts +43 -32
  241. package/dist/core/Step.d.ts.map +1 -1
  242. package/dist/core/Step.js +220 -126
  243. package/dist/core/Step.js.map +1 -1
  244. package/dist/core/StreamingToolExecutor.d.ts +2 -2
  245. package/dist/core/StreamingToolExecutor.d.ts.map +1 -1
  246. package/dist/core/StreamingToolExecutor.js.map +1 -1
  247. package/dist/core/ToolManager.d.ts +44 -13
  248. package/dist/core/ToolManager.d.ts.map +1 -1
  249. package/dist/core/ToolManager.js +174 -91
  250. package/dist/core/ToolManager.js.map +1 -1
  251. package/dist/core/createAgent.d.ts +35 -0
  252. package/dist/core/createAgent.d.ts.map +1 -0
  253. package/dist/core/createAgent.js +36 -0
  254. package/dist/core/createAgent.js.map +1 -0
  255. package/dist/core/flow-namespace.d.ts +49 -0
  256. package/dist/core/flow-namespace.d.ts.map +1 -0
  257. package/dist/core/flow-namespace.js +168 -0
  258. package/dist/core/flow-namespace.js.map +1 -0
  259. package/dist/index.d.ts +11 -14
  260. package/dist/index.d.ts.map +1 -1
  261. package/dist/index.js +9 -12
  262. package/dist/index.js.map +1 -1
  263. package/dist/providers/GeminiProvider.d.ts +3 -3
  264. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  265. package/dist/providers/GeminiProvider.js +16 -14
  266. package/dist/providers/GeminiProvider.js.map +1 -1
  267. package/dist/types/agent.d.ts +183 -54
  268. package/dist/types/agent.d.ts.map +1 -1
  269. package/dist/types/agent.js +0 -6
  270. package/dist/types/agent.js.map +1 -1
  271. package/dist/types/ai.d.ts +3 -3
  272. package/dist/types/ai.d.ts.map +1 -1
  273. package/dist/types/errors.d.ts +15 -0
  274. package/dist/types/errors.d.ts.map +1 -0
  275. package/dist/types/errors.js +18 -0
  276. package/dist/types/errors.js.map +1 -0
  277. package/dist/types/flow.d.ts +513 -0
  278. package/dist/types/flow.d.ts.map +1 -0
  279. package/dist/types/flow.js +5 -0
  280. package/dist/types/flow.js.map +1 -0
  281. package/dist/types/index.d.ts +7 -6
  282. package/dist/types/index.d.ts.map +1 -1
  283. package/dist/types/index.js +4 -1
  284. package/dist/types/index.js.map +1 -1
  285. package/dist/types/persistence.d.ts +11 -7
  286. package/dist/types/persistence.d.ts.map +1 -1
  287. package/dist/types/routing.d.ts +1 -1
  288. package/dist/types/routing.d.ts.map +1 -1
  289. package/dist/types/session.d.ts +24 -23
  290. package/dist/types/session.d.ts.map +1 -1
  291. package/dist/types/signals.d.ts +248 -0
  292. package/dist/types/signals.d.ts.map +1 -0
  293. package/dist/types/signals.js +10 -0
  294. package/dist/types/signals.js.map +1 -0
  295. package/dist/types/template.d.ts +2 -8
  296. package/dist/types/template.d.ts.map +1 -1
  297. package/dist/types/tool.d.ts +36 -29
  298. package/dist/types/tool.d.ts.map +1 -1
  299. package/dist/types/tool.js +1 -1
  300. package/dist/types/tool.js.map +1 -1
  301. package/dist/utils/condition.d.ts +7 -1
  302. package/dist/utils/condition.d.ts.map +1 -1
  303. package/dist/utils/condition.js.map +1 -1
  304. package/dist/utils/id.d.ts +13 -5
  305. package/dist/utils/id.d.ts.map +1 -1
  306. package/dist/utils/id.js +22 -9
  307. package/dist/utils/id.js.map +1 -1
  308. package/dist/utils/index.d.ts +2 -2
  309. package/dist/utils/index.d.ts.map +1 -1
  310. package/dist/utils/index.js +2 -2
  311. package/dist/utils/index.js.map +1 -1
  312. package/dist/utils/session.d.ts +44 -5
  313. package/dist/utils/session.d.ts.map +1 -1
  314. package/dist/utils/session.js +193 -37
  315. package/dist/utils/session.js.map +1 -1
  316. package/docs/README.md +15 -202
  317. package/docs/concepts/architecture.md +281 -0
  318. package/docs/concepts/directives.md +400 -0
  319. package/docs/concepts/pipeline.md +399 -0
  320. package/docs/guides/branching.md +263 -0
  321. package/docs/guides/compaction.md +163 -0
  322. package/docs/guides/conditions.md +167 -0
  323. package/docs/guides/error-handling.md +176 -0
  324. package/docs/guides/flow-control.md +409 -0
  325. package/docs/guides/instructions.md +210 -0
  326. package/docs/guides/persistence.md +182 -0
  327. package/docs/guides/streaming.md +137 -0
  328. package/docs/migration/README.md +15 -0
  329. package/docs/migration/route-to-flow.md +560 -0
  330. package/docs/migration/v1-to-v2.md +909 -0
  331. package/docs/reference/adapters.md +481 -0
  332. package/docs/reference/branches.md +241 -0
  333. package/docs/reference/create-agent.md +186 -0
  334. package/docs/reference/directive.md +243 -0
  335. package/docs/reference/errors.md +122 -0
  336. package/docs/reference/flow.md +238 -0
  337. package/docs/reference/instruction.md +177 -0
  338. package/docs/reference/pre-directive.md +131 -0
  339. package/docs/reference/providers.md +227 -0
  340. package/docs/reference/signals.md +356 -0
  341. package/docs/reference/step.md +339 -0
  342. package/docs/reference/tool.md +269 -0
  343. package/docs/start/01-install.md +81 -0
  344. package/docs/start/02-first-agent.md +196 -0
  345. package/docs/start/03-collect-data.md +222 -0
  346. package/docs/start/04-add-tools.md +276 -0
  347. package/docs/start/05-go-to-production.md +216 -0
  348. package/examples/01-quickstart.ts +20 -0
  349. package/examples/02-data-extraction.ts +90 -0
  350. package/examples/03-tools.ts +136 -0
  351. package/examples/04-instructions.ts +100 -0
  352. package/examples/05-branching.ts +140 -0
  353. package/examples/06-flow-control.ts +103 -0
  354. package/examples/07-streaming.ts +69 -0
  355. package/examples/08-persistence.ts +98 -0
  356. package/examples/09-signals.ts +144 -0
  357. package/examples/tsconfig.json +30 -0
  358. package/package.json +2 -1
  359. package/src/adapters/MemoryAdapter.ts +3 -3
  360. package/src/adapters/MongoAdapter.ts +3 -3
  361. package/src/adapters/OpenSearchAdapter.ts +10 -8
  362. package/src/adapters/PostgreSQLAdapter.ts +26 -10
  363. package/src/adapters/PrismaAdapter.ts +6 -6
  364. package/src/adapters/RedisAdapter.ts +3 -3
  365. package/src/adapters/SQLiteAdapter.ts +31 -12
  366. package/src/constants/index.ts +2 -10
  367. package/src/core/Agent.ts +585 -374
  368. package/src/core/AutoChainExecutor.ts +440 -0
  369. package/src/core/BranchEvaluator.ts +167 -0
  370. package/src/core/DirectiveBus.ts +248 -0
  371. package/src/core/DirectiveChainTracker.ts +144 -0
  372. package/src/core/Flow.ts +666 -0
  373. package/src/core/{RoutingEngine.ts → FlowRouter.ts} +385 -365
  374. package/src/core/PersistenceManager.ts +8 -8
  375. package/src/core/PromptComposer.ts +209 -140
  376. package/src/core/PromptSectionCache.ts +1 -1
  377. package/src/core/ResponseEngine.ts +61 -46
  378. package/src/core/ResponseModal.ts +1458 -1241
  379. package/src/core/ResponsePipeline.ts +675 -173
  380. package/src/core/SignalEvaluator.ts +420 -0
  381. package/src/core/SignalProcessor.ts +723 -0
  382. package/src/core/Step.ts +279 -176
  383. package/src/core/StreamingToolExecutor.ts +4 -4
  384. package/src/core/ToolManager.ts +200 -97
  385. package/src/core/createAgent.ts +40 -0
  386. package/src/core/flow-namespace.ts +219 -0
  387. package/src/index.ts +42 -36
  388. package/src/providers/GeminiProvider.ts +17 -15
  389. package/src/types/agent.ts +182 -53
  390. package/src/types/ai.ts +3 -3
  391. package/src/types/errors.ts +18 -0
  392. package/src/types/flow.ts +590 -0
  393. package/src/types/index.ts +43 -16
  394. package/src/types/persistence.ts +12 -8
  395. package/src/types/routing.ts +1 -1
  396. package/src/types/session.ts +26 -23
  397. package/src/types/signals.ts +321 -0
  398. package/src/types/template.ts +3 -11
  399. package/src/types/tool.ts +50 -42
  400. package/src/utils/condition.ts +13 -4
  401. package/src/utils/id.ts +27 -9
  402. package/src/utils/index.ts +6 -2
  403. package/src/utils/session.ts +238 -42
  404. package/dist/cjs/core/BatchExecutor.d.ts +0 -359
  405. package/dist/cjs/core/BatchExecutor.d.ts.map +0 -1
  406. package/dist/cjs/core/BatchExecutor.js +0 -861
  407. package/dist/cjs/core/BatchExecutor.js.map +0 -1
  408. package/dist/cjs/core/BatchPromptBuilder.d.ts +0 -89
  409. package/dist/cjs/core/BatchPromptBuilder.d.ts.map +0 -1
  410. package/dist/cjs/core/BatchPromptBuilder.js +0 -223
  411. package/dist/cjs/core/BatchPromptBuilder.js.map +0 -1
  412. package/dist/cjs/core/Route.d.ts +0 -180
  413. package/dist/cjs/core/Route.d.ts.map +0 -1
  414. package/dist/cjs/core/Route.js +0 -542
  415. package/dist/cjs/core/Route.js.map +0 -1
  416. package/dist/cjs/core/RoutingEngine.d.ts +0 -185
  417. package/dist/cjs/core/RoutingEngine.d.ts.map +0 -1
  418. package/dist/cjs/core/RoutingEngine.js.map +0 -1
  419. package/dist/cjs/types/route.d.ts +0 -336
  420. package/dist/cjs/types/route.d.ts.map +0 -1
  421. package/dist/cjs/types/route.js.map +0 -1
  422. package/dist/core/BatchExecutor.d.ts +0 -359
  423. package/dist/core/BatchExecutor.d.ts.map +0 -1
  424. package/dist/core/BatchExecutor.js +0 -856
  425. package/dist/core/BatchExecutor.js.map +0 -1
  426. package/dist/core/BatchPromptBuilder.d.ts +0 -89
  427. package/dist/core/BatchPromptBuilder.d.ts.map +0 -1
  428. package/dist/core/BatchPromptBuilder.js +0 -219
  429. package/dist/core/BatchPromptBuilder.js.map +0 -1
  430. package/dist/core/Route.d.ts +0 -180
  431. package/dist/core/Route.d.ts.map +0 -1
  432. package/dist/core/Route.js +0 -538
  433. package/dist/core/Route.js.map +0 -1
  434. package/dist/core/RoutingEngine.d.ts +0 -185
  435. package/dist/core/RoutingEngine.d.ts.map +0 -1
  436. package/dist/core/RoutingEngine.js.map +0 -1
  437. package/dist/types/route.d.ts +0 -336
  438. package/dist/types/route.d.ts.map +0 -1
  439. package/dist/types/route.js +0 -5
  440. package/dist/types/route.js.map +0 -1
  441. package/docs/CONTRIBUTING.md +0 -521
  442. package/docs/api/README.md +0 -3299
  443. package/docs/api/overview.md +0 -1410
  444. package/docs/architecture/data-extraction-flow.md +0 -360
  445. package/docs/architecture/multi-step-execution.md +0 -277
  446. package/docs/core/agent/README.md +0 -938
  447. package/docs/core/agent/context-management.md +0 -796
  448. package/docs/core/agent/rules-and-prohibitions.md +0 -113
  449. package/docs/core/agent/session-management.md +0 -693
  450. package/docs/core/ai-integration/prompt-composition.md +0 -355
  451. package/docs/core/ai-integration/providers.md +0 -515
  452. package/docs/core/ai-integration/response-processing.md +0 -433
  453. package/docs/core/conversation-flows/data-collection.md +0 -772
  454. package/docs/core/conversation-flows/route-dsl.md +0 -509
  455. package/docs/core/conversation-flows/routes.md +0 -249
  456. package/docs/core/conversation-flows/step-transitions.md +0 -731
  457. package/docs/core/conversation-flows/steps.md +0 -268
  458. package/docs/core/error-handling.md +0 -830
  459. package/docs/core/persistence/adapters.md +0 -255
  460. package/docs/core/persistence/session-storage.md +0 -656
  461. package/docs/core/routing/intelligent-routing.md +0 -470
  462. package/docs/core/tools/enhanced-tool.md +0 -186
  463. package/docs/core/tools/streaming-execution.md +0 -161
  464. package/docs/core/tools/tool-definition.md +0 -970
  465. package/docs/core/tools/tool-scoping.md +0 -819
  466. package/docs/guides/advanced-patterns/publishing.md +0 -186
  467. package/docs/guides/context-compaction.md +0 -96
  468. package/docs/guides/error-handling-patterns.md +0 -578
  469. package/docs/guides/getting-started/README.md +0 -795
  470. package/docs/guides/migration/README.md +0 -101
  471. package/docs/guides/migration/flexible-routing-conditions.md +0 -375
  472. package/docs/guides/migration/multi-step-execution.md +0 -393
  473. package/docs/guides/migration/response-modal-refactor.md +0 -518
  474. package/docs/guides/prompt-optimization.md +0 -164
  475. package/examples/advanced-patterns/context-compaction.ts +0 -223
  476. package/examples/advanced-patterns/knowledge-based-agent.ts +0 -735
  477. package/examples/advanced-patterns/persistent-onboarding.ts +0 -728
  478. package/examples/advanced-patterns/route-lifecycle-hooks.ts +0 -556
  479. package/examples/advanced-patterns/streaming-responses.ts +0 -656
  480. package/examples/ai-providers/anthropic-integration.ts +0 -388
  481. package/examples/ai-providers/openai-integration.ts +0 -228
  482. package/examples/condition-patterns/function-only-conditions.ts +0 -365
  483. package/examples/condition-patterns/mixed-array-conditions.ts +0 -477
  484. package/examples/condition-patterns/route-skipif-patterns.ts +0 -468
  485. package/examples/condition-patterns/step-skipif-patterns.ts +0 -0
  486. package/examples/condition-patterns/string-only-conditions.ts +0 -296
  487. package/examples/conversation-flows/completion-transitions.ts +0 -318
  488. package/examples/core-concepts/basic-agent.ts +0 -503
  489. package/examples/core-concepts/modern-streaming-api.ts +0 -309
  490. package/examples/core-concepts/schema-driven-extraction.ts +0 -332
  491. package/examples/core-concepts/session-management.ts +0 -494
  492. package/examples/integrations/database-integration.ts +0 -631
  493. package/examples/integrations/healthcare-integration.ts +0 -595
  494. package/examples/integrations/search-integration.ts +0 -530
  495. package/examples/integrations/server-session-management.ts +0 -307
  496. package/examples/persistence/custom-adapter.ts +0 -526
  497. package/examples/persistence/database-persistence.ts +0 -583
  498. package/examples/persistence/memory-sessions.ts +0 -495
  499. package/examples/persistence/prisma-schema.example.prisma +0 -74
  500. package/examples/persistence/redis-persistence.ts +0 -488
  501. package/examples/tools/basic-tools.ts +0 -765
  502. package/examples/tools/data-enrichment-tools.ts +0 -593
  503. package/examples/tools/enhanced-tool-metadata.ts +0 -268
  504. package/examples/tools/streaming-tool-execution.ts +0 -283
  505. package/src/core/BatchExecutor.ts +0 -1187
  506. package/src/core/BatchPromptBuilder.ts +0 -299
  507. package/src/core/Route.ts +0 -678
  508. package/src/types/route.ts +0 -392
@@ -1,1187 +0,0 @@
1
- /**
2
- * BatchExecutor - Core component for multi-step execution
3
- *
4
- * Responsible for determining which Steps can execute together in a single batch
5
- * and orchestrating their execution with a single LLM call.
6
- */
7
-
8
- import type {
9
- BatchResult,
10
- StoppedReason,
11
- StepOptions,
12
- BatchExecutionError,
13
- BatchExecutionResult,
14
- StepRef,
15
- BatchExecutionEvent,
16
- BatchExecutionEventListener,
17
- BatchExecutionTiming,
18
- } from '../types/route';
19
- import type { SessionState } from '../types/session';
20
- import type { Tool } from '../types/tool';
21
- import type { StructuredSchema } from '../types/schema';
22
- import { Step } from './Step';
23
- import { Route } from './Route';
24
- import { END_ROUTE_ID } from '../constants';
25
- import { logger, createTemplateContext, mergeCollected, createSession } from '../utils';
26
-
27
- /**
28
- * Step configuration relevant for needs-input detection
29
- */
30
- export interface NeedsInputStep {
31
- /** Required data fields that must be present before entering this step */
32
- requires?: readonly (string | number | symbol)[];
33
- /** Fields to collect from the conversation in this step */
34
- collect?: readonly (string | number | symbol)[];
35
- }
36
-
37
- /**
38
- * Determine if a Step needs user input to proceed
39
- *
40
- * IMPORTANT: sessionData MUST already include pre-extracted fields.
41
- * This function is called AFTER pre-extraction has been merged into session data.
42
- *
43
- * A Step needs input when:
44
- * 1. It has `requires` fields and at least one is missing from session data (after pre-extraction)
45
- * 2. It has non-empty `collect` fields and none of those fields have data (after pre-extraction)
46
- *
47
- * @param step - The Step to evaluate (can be Step instance or StepOptions)
48
- * @param sessionDataAfterPreExtraction - Session data with pre-extracted fields already merged
49
- * @returns true if the step needs user input, false otherwise
50
- *
51
- * @example
52
- * ```typescript
53
- * // Step with requires - needs input if any required field is missing
54
- * const step = { requires: ['name', 'email'], collect: [] };
55
- * needsInput(step, { name: 'John' }); // true - email is missing
56
- * needsInput(step, { name: 'John', email: 'john@example.com' }); // false - all present
57
- *
58
- * // Step with collect - needs input if no collect fields have data
59
- * const step2 = { collect: ['preference', 'feedback'] };
60
- * needsInput(step2, {}); // true - no collect fields have data
61
- * needsInput(step2, { preference: 'A' }); // false - at least one has data
62
- * ```
63
- *
64
- * **Validates: Requirements 1.2, 1.3**
65
- */
66
- export function needsInput<TData extends Record<string, unknown> = Record<string, unknown>>(
67
- step: NeedsInputStep,
68
- sessionDataAfterPreExtraction: Partial<TData>
69
- ): boolean {
70
- // Check requires - all must be present (after pre-extraction)
71
- // Requirement 1.2: A Step Needs_Input WHEN it has `requires` fields that are not present
72
- // in session data after Pre_Extraction
73
- if (step.requires && step.requires.length > 0) {
74
- const missingRequired = step.requires.some(
75
- field => {
76
- const key = String(field);
77
- return (sessionDataAfterPreExtraction as Record<string, unknown>)[key] === undefined;
78
- }
79
- );
80
- if (missingRequired) return true;
81
- }
82
-
83
- // Check collect - needs input if collecting and no data exists (after pre-extraction)
84
- // Requirement 1.3: A Step Needs_Input WHEN it has `collect` fields (non-empty array) and
85
- // no data for those fields exists in session data
86
- if (step.collect && step.collect.length > 0) {
87
- const hasAnyCollectData = step.collect.some(
88
- field => {
89
- const key = String(field);
90
- return (sessionDataAfterPreExtraction as Record<string, unknown>)[key] !== undefined;
91
- }
92
- );
93
- if (!hasAnyCollectData) return true;
94
- }
95
-
96
- return false;
97
- }
98
-
99
- /**
100
- * Parameters for batch determination
101
- */
102
- export interface DetermineBatchParams<TContext, TData> {
103
- /** The route containing the steps */
104
- route: Route<TContext, TData>;
105
- /** The current step to start from (undefined means start from initial step) */
106
- currentStep: Step<TContext, TData> | undefined;
107
- /** Session data with pre-extracted fields already merged */
108
- sessionData: Partial<TData>;
109
- /** Agent context for condition evaluation */
110
- context: TContext;
111
- /**
112
- * Maximum number of steps to include in this batch.
113
- * When reached, the batch stops with 'max_steps_reached'.
114
- * Defaults to 1 (single-step execution).
115
- */
116
- maxSteps?: number;
117
- }
118
-
119
- /**
120
- * BatchExecutor class - orchestrates multi-step execution
121
- *
122
- * Determines which Steps can execute together in a single batch based on:
123
- * - skipIf conditions (skip steps that evaluate to true)
124
- * - needsInput detection (stop when a step needs user input)
125
- * - END_ROUTE detection (stop when reaching end of route)
126
- *
127
- * Supports event emission for debugging and observability:
128
- * - batch_start: Emitted when batch determination begins
129
- * - step_included: Emitted when a step is included in the batch
130
- * - step_skipped: Emitted when a step is skipped (due to skipIf)
131
- * - batch_stop: Emitted when batch determination stops
132
- * - batch_complete: Emitted when batch execution completes
133
- *
134
- * **Validates: Requirements 1.1, 1.4, 1.5, 7.1, 7.2, 7.3, 11.1, 11.2, 11.3**
135
- */
136
- export class BatchExecutor<TContext = unknown, TData = unknown> {
137
- /** Event listeners for batch execution events */
138
- private eventListeners: BatchExecutionEventListener[] = [];
139
-
140
- /**
141
- * Add an event listener for batch execution events
142
- *
143
- * @param listener - Callback function to receive events
144
- * @returns Function to remove the listener
145
- *
146
- * **Validates: Requirements 11.3**
147
- */
148
- addEventListener(listener: BatchExecutionEventListener): () => void {
149
- this.eventListeners.push(listener);
150
- return () => {
151
- const index = this.eventListeners.indexOf(listener);
152
- if (index !== -1) {
153
- this.eventListeners.splice(index, 1);
154
- }
155
- };
156
- }
157
-
158
- /**
159
- * Remove an event listener
160
- *
161
- * @param listener - The listener to remove
162
- */
163
- removeEventListener(listener: BatchExecutionEventListener): void {
164
- const index = this.eventListeners.indexOf(listener);
165
- if (index !== -1) {
166
- this.eventListeners.splice(index, 1);
167
- }
168
- }
169
-
170
- /**
171
- * Emit a batch execution event to all listeners
172
- *
173
- * @param event - The event to emit
174
- * @private
175
- */
176
- private emitEvent(event: BatchExecutionEvent): void {
177
- for (const listener of this.eventListeners) {
178
- try {
179
- listener(event);
180
- } catch (error) {
181
- // Log but don't fail on listener errors
182
- logger.warn(`[BatchExecutor] Event listener error:`, error);
183
- }
184
- }
185
- }
186
-
187
- /**
188
- * Create and emit a batch execution event
189
- *
190
- * @param type - Event type
191
- * @param details - Event details
192
- * @private
193
- */
194
- private emitBatchEvent(
195
- type: BatchExecutionEvent['type'],
196
- details: BatchExecutionEvent['details']
197
- ): void {
198
- const event: BatchExecutionEvent = {
199
- type,
200
- timestamp: new Date(),
201
- details,
202
- };
203
- this.emitEvent(event);
204
-
205
- // Also log the event when debug mode is enabled
206
- logger.debug(`[BatchExecutor] Event: ${type}`, details);
207
- }
208
-
209
- /**
210
- * Determine which Steps can execute in the current batch
211
- * starting from the given Step position.
212
- *
213
- * Algorithm:
214
- * 1. Start from currentStep (or initialStep if undefined)
215
- * 2. For each step:
216
- * a. Check if it's END_ROUTE - stop with 'end_route'
217
- * b. Evaluate skipIf condition
218
- * c. If skipIf is true - skip step, continue to next
219
- * d. If skipIf throws error - treat as non-skippable (Requirement 7.3)
220
- * e. Evaluate needsInput
221
- * f. If needsInput is false - include in batch, continue to next
222
- * g. If needsInput is true - stop with 'needs_input'
223
- * 3. If all steps processed - stop with 'route_complete'
224
- *
225
- * @param params - Parameters for batch determination
226
- * @returns BatchResult with steps to execute and stopping reason
227
- *
228
- * **Validates: Requirements 1.1, 1.4, 1.5, 7.1, 7.2, 7.3**
229
- */
230
- async determineBatch(params: DetermineBatchParams<TContext, TData>): Promise<BatchResult<TContext, TData>> {
231
- const { route, currentStep, sessionData, context, maxSteps = 1 } = params;
232
- const startTime = Date.now();
233
-
234
- const batchSteps: StepOptions<TContext, TData>[] = [];
235
- let stoppedReason: StoppedReason = 'route_complete';
236
- let stoppedAtStep: StepOptions<TContext, TData> | undefined;
237
-
238
- // Get all steps in the route for traversal
239
- const allSteps = route.getAllSteps();
240
-
241
- // Find starting position
242
- let startIndex = 0;
243
- if (currentStep) {
244
- const currentIndex = allSteps.findIndex(s => s.id === currentStep.id);
245
- if (currentIndex !== -1) {
246
- startIndex = currentIndex;
247
- }
248
- }
249
-
250
- // Log batch determination start (Requirement 11.1)
251
- logger.debug(`[BatchExecutor] Starting batch determination from step index ${startIndex}, total steps: ${allSteps.length}`);
252
-
253
- // Emit batch_start event (Requirement 11.3)
254
- this.emitBatchEvent('batch_start', {
255
- stepId: currentStep?.id,
256
- reason: `Starting batch determination from ${currentStep?.id || 'initial step'}`,
257
- batchSize: 0,
258
- });
259
-
260
- // Create template context for condition evaluation
261
- const templateContext = createTemplateContext<TContext, TData>({
262
- context,
263
- data: sessionData,
264
- session: createSession<TData>({ data: sessionData }),
265
- });
266
-
267
- // Walk through steps starting from current position
268
- for (let i = startIndex; i < allSteps.length; i++) {
269
- const step = allSteps[i];
270
- const stepOptions = step.toOptions();
271
-
272
- // Check for END_ROUTE (Requirement 2.2)
273
- if (step.id === END_ROUTE_ID) {
274
- stoppedReason = 'end_route';
275
- stoppedAtStep = stepOptions;
276
-
277
- // Log stopping reason (Requirement 11.2)
278
- logger.debug(`[BatchExecutor] Reached END_ROUTE, stopping batch`);
279
-
280
- // Emit batch_stop event (Requirement 11.3)
281
- this.emitBatchEvent('batch_stop', {
282
- stepId: step.id,
283
- reason: 'Reached END_ROUTE',
284
- stoppedReason: 'end_route',
285
- batchSize: batchSteps.length,
286
- });
287
- break;
288
- }
289
-
290
- // Evaluate skipIf condition (Requirements 7.1, 7.2, 7.3)
291
- let shouldSkip = false;
292
- if (step.skipIf) {
293
- try {
294
- const skipResult = await step.evaluateSkipIf(templateContext);
295
- shouldSkip = skipResult.shouldSkip;
296
-
297
- // Log skipIf evaluation (Requirement 11.1)
298
- logger.debug(`[BatchExecutor] Step ${step.id} skipIf evaluated to: ${shouldSkip}`);
299
- } catch (error) {
300
- // Requirement 7.3: If skipIf evaluation throws an error, treat as non-skippable
301
- logger.warn(`[BatchExecutor] skipIf evaluation error for step ${step.id}, treating as non-skippable:`, error);
302
- shouldSkip = false;
303
- }
304
- }
305
-
306
- // If skipIf is true, skip this step and continue (Requirement 7.2)
307
- if (shouldSkip) {
308
- // Log step skip (Requirement 11.1)
309
- logger.debug(`[BatchExecutor] Skipping step ${step.id} due to skipIf condition`);
310
-
311
- // Emit step_skipped event (Requirement 11.3)
312
- this.emitBatchEvent('step_skipped', {
313
- stepId: step.id,
314
- reason: 'skipIf condition evaluated to true',
315
- });
316
- continue;
317
- }
318
-
319
- // Evaluate needsInput (Requirements 1.2, 1.3)
320
- const stepNeedsInput = needsInput(step, sessionData);
321
-
322
- if (stepNeedsInput) {
323
- // Requirement 1.5: Stop when a step needs input
324
- stoppedReason = 'needs_input';
325
- stoppedAtStep = stepOptions;
326
-
327
- // Log stopping reason with details (Requirement 11.1, 11.2)
328
- const missingRequires = step.requires?.filter(
329
- field => (sessionData as Record<string, unknown>)[String(field)] === undefined
330
- ) || [];
331
- const collectFields = step.collect || [];
332
-
333
- // Warn about missing required fields from previous steps
334
- if (missingRequires.length > 0) {
335
- const warning = `[Agent] Step "${step.description || step.id}" requires data [${missingRequires.join(', ')}] that was not collected by previous steps. ` +
336
- `Ensure earlier steps collect these fields before this step can proceed.`;
337
- logger.warn(warning);
338
-
339
- // Also log to console for developer visibility (but silence in test suites to prevent fast-check spam)
340
- if (process.env.NODE_ENV !== 'test') {
341
- console.warn(warning);
342
- }
343
- }
344
-
345
- logger.debug(`[BatchExecutor] Step ${step.id} needs input, stopping batch. Missing requires: [${missingRequires.join(', ')}], Collect fields: [${collectFields.join(', ')}]`);
346
-
347
- // Emit batch_stop event (Requirement 11.3)
348
- this.emitBatchEvent('batch_stop', {
349
- stepId: step.id,
350
- reason: `Step needs input - missing requires: [${missingRequires.join(', ')}], collect fields: [${collectFields.join(', ')}]`,
351
- stoppedReason: 'needs_input',
352
- batchSize: batchSteps.length,
353
- });
354
- break;
355
- }
356
-
357
- // Requirement 1.4: Step doesn't need input, include in batch
358
- batchSteps.push(stepOptions);
359
-
360
- // Log step inclusion with reason (Requirement 11.1)
361
- logger.debug(`[BatchExecutor] Including step ${step.id} in batch (all requirements satisfied)`);
362
-
363
- // Emit step_included event (Requirement 11.3)
364
- this.emitBatchEvent('step_included', {
365
- stepId: step.id,
366
- reason: 'All requirements satisfied, no input needed',
367
- batchSize: batchSteps.length,
368
- });
369
-
370
- // Check if we've reached the max steps limit
371
- if (batchSteps.length >= maxSteps) {
372
- stoppedReason = 'max_steps_reached';
373
-
374
- logger.debug(`[BatchExecutor] Reached maxStepsPerBatch limit (${maxSteps}), stopping batch`);
375
-
376
- this.emitBatchEvent('batch_stop', {
377
- stepId: step.id,
378
- reason: `Reached maxStepsPerBatch limit (${maxSteps})`,
379
- stoppedReason: 'max_steps_reached',
380
- batchSize: batchSteps.length,
381
- });
382
- break;
383
- }
384
-
385
- // Move to next step in the sequence
386
- const transitions = step.getTransitions();
387
- if (transitions.length === 0) {
388
- // No more transitions, route is complete
389
- stoppedReason = 'route_complete';
390
-
391
- // Log stopping reason (Requirement 11.2)
392
- logger.debug(`[BatchExecutor] No more transitions from step ${step.id}, route complete`);
393
-
394
- // Emit batch_stop event (Requirement 11.3)
395
- this.emitBatchEvent('batch_stop', {
396
- stepId: step.id,
397
- reason: 'No more transitions, route complete',
398
- stoppedReason: 'route_complete',
399
- batchSize: batchSteps.length,
400
- });
401
- break;
402
- }
403
-
404
- // For linear routes, follow the first transition
405
- // For branching routes, we'd need more complex logic
406
- const nextStep = transitions[0];
407
- if (nextStep) {
408
- // Update the loop to continue from the next step
409
- const nextIndex = allSteps.findIndex(s => s.id === nextStep.id);
410
- if (nextIndex !== -1 && nextIndex > i) {
411
- // Continue from next step (will be incremented by loop)
412
- i = nextIndex - 1;
413
- } else if (nextStep.id === END_ROUTE_ID) {
414
- // Next step is END_ROUTE
415
- stoppedReason = 'end_route';
416
- stoppedAtStep = nextStep.toOptions();
417
-
418
- // Log stopping reason (Requirement 11.2)
419
- logger.debug(`[BatchExecutor] Next step is END_ROUTE, stopping batch`);
420
-
421
- // Emit batch_stop event (Requirement 11.3)
422
- this.emitBatchEvent('batch_stop', {
423
- stepId: nextStep.id,
424
- reason: 'Next step is END_ROUTE',
425
- stoppedReason: 'end_route',
426
- batchSize: batchSteps.length,
427
- });
428
- break;
429
- }
430
- }
431
- }
432
-
433
- // Log batch determination complete with timing (Requirement 11.1, 11.2)
434
- const determinationTime = Date.now() - startTime;
435
- logger.debug(`[BatchExecutor] Batch determination complete. Steps: ${batchSteps.length}, Stopped reason: ${stoppedReason}, Time: ${determinationTime}ms`);
436
-
437
- return {
438
- steps: batchSteps,
439
- stoppedReason,
440
- stoppedAtStep,
441
- };
442
- }
443
-
444
- /**
445
- * Execute prepare hooks for all steps in the batch
446
- *
447
- * Executes all prepare hooks in Step order before the LLM call.
448
- * If any prepare hook fails, execution stops immediately and returns an error.
449
- *
450
- * @param params - Parameters for hook execution
451
- * @returns Result indicating success or failure with error details
452
- *
453
- * **Validates: Requirements 5.1, 5.3, 5.4**
454
- */
455
- async executePrepareHooks(params: ExecuteHooksParams<TContext, TData>): Promise<HookExecutionResult> {
456
- const { steps, context, data, executeHook } = params;
457
- const executedSteps: string[] = [];
458
-
459
- logger.debug(`[BatchExecutor] Executing prepare hooks for ${steps.length} steps`);
460
-
461
- for (const step of steps) {
462
- if (step.prepare) {
463
- logger.debug(`[BatchExecutor] Executing prepare hook for step: ${step.id}`);
464
-
465
- try {
466
- await executeHook(step.prepare, context, data, step);
467
- executedSteps.push(step.id || 'unknown');
468
- logger.debug(`[BatchExecutor] Prepare hook completed for step: ${step.id}`);
469
- } catch (error) {
470
- // Requirement 5.4: Stop on prepare hook failure
471
- const errorMessage = error instanceof Error ? error.message : String(error);
472
- logger.error(`[BatchExecutor] Prepare hook failed for step ${step.id}: ${errorMessage}`);
473
-
474
- return {
475
- success: false,
476
- executedSteps,
477
- error: {
478
- type: 'prepare_hook',
479
- message: errorMessage,
480
- stepId: step.id,
481
- details: error,
482
- },
483
- };
484
- }
485
- }
486
- }
487
-
488
- logger.debug(`[BatchExecutor] All prepare hooks completed successfully`);
489
- return {
490
- success: true,
491
- executedSteps,
492
- };
493
- }
494
-
495
- /**
496
- * Execute finalize hooks for all steps in the batch
497
- *
498
- * Executes all finalize hooks in Step order after the LLM response.
499
- * If a finalize hook fails, the error is logged but execution continues
500
- * with remaining hooks.
501
- *
502
- * @param params - Parameters for hook execution
503
- * @returns Result with any errors that occurred (always succeeds)
504
- *
505
- * **Validates: Requirements 5.2, 5.3, 5.5**
506
- */
507
- async executeFinalizeHooks(params: ExecuteHooksParams<TContext, TData>): Promise<HookExecutionResult> {
508
- const { steps, context, data, executeHook } = params;
509
- const executedSteps: string[] = [];
510
- const errors: Array<{ stepId: string; error: BatchExecutionError }> = [];
511
-
512
- logger.debug(`[BatchExecutor] Executing finalize hooks for ${steps.length} steps`);
513
-
514
- for (const step of steps) {
515
- if (step.finalize) {
516
- logger.debug(`[BatchExecutor] Executing finalize hook for step: ${step.id}`);
517
-
518
- try {
519
- await executeHook(step.finalize, context, data, step);
520
- executedSteps.push(step.id || 'unknown');
521
- logger.debug(`[BatchExecutor] Finalize hook completed for step: ${step.id}`);
522
- } catch (error) {
523
- // Requirement 5.5: Log error and continue with remaining hooks
524
- const errorMessage = error instanceof Error ? error.message : String(error);
525
- logger.error(`[BatchExecutor] Finalize hook failed for step ${step.id}: ${errorMessage}`);
526
-
527
- errors.push({
528
- stepId: step.id || 'unknown',
529
- error: {
530
- type: 'finalize_hook',
531
- message: errorMessage,
532
- stepId: step.id,
533
- details: error,
534
- },
535
- });
536
-
537
- // Continue to next step despite error
538
- }
539
- }
540
- }
541
-
542
- if (errors.length > 0) {
543
- logger.warn(`[BatchExecutor] ${errors.length} finalize hook(s) failed, but execution continued`);
544
- } else {
545
- logger.debug(`[BatchExecutor] All finalize hooks completed successfully`);
546
- }
547
-
548
- // Always return success for finalize hooks (errors are logged but don't stop execution)
549
- return {
550
- success: true,
551
- executedSteps,
552
- errors: errors.length > 0 ? errors : undefined,
553
- };
554
- }
555
-
556
- /**
557
- * Execute all hooks for a batch of steps
558
- *
559
- * This is a convenience method that executes prepare hooks, then allows
560
- * the caller to perform the LLM call, and finally executes finalize hooks.
561
- *
562
- * @param params - Parameters for hook execution
563
- * @returns Object with methods to execute prepare and finalize phases
564
- *
565
- * **Validates: Requirements 5.1, 5.2, 5.3, 5.4, 5.5**
566
- */
567
- createHookExecutor(params: ExecuteHooksParams<TContext, TData>): HookExecutor<TContext, TData> {
568
- return {
569
- executePrepare: () => this.executePrepareHooks(params),
570
- executeFinalize: () => this.executeFinalizeHooks(params),
571
- };
572
- }
573
-
574
- /**
575
- * Execute a batch of steps with comprehensive error handling
576
- *
577
- * This method orchestrates the complete batch execution flow:
578
- * 1. Execute prepare hooks (stop on failure)
579
- * 2. Make LLM call (preserve session state on failure)
580
- * 3. Collect and validate data (include errors in response)
581
- * 4. Execute finalize hooks (continue on failure, log errors)
582
- *
583
- * Error handling behavior:
584
- * - LLM call failures: Return error response with last successful session state
585
- * - Validation failures: Include validation errors in response, preserve partial data
586
- * - Prepare hook failures: Stop execution, return error with appropriate stoppedReason
587
- * - Finalize hook failures: Log errors, continue execution (non-fatal)
588
- *
589
- * @param params - Parameters for batch execution
590
- * @returns BatchExecutionResult with message, session, executed steps, and any errors
591
- *
592
- * **Validates: Requirements 9.1, 9.2, 9.3, 2.4**
593
- */
594
- async executeBatch(params: ExecuteBatchParams<TContext, TData>): Promise<BatchExecutionResult<TData>> {
595
- const {
596
- batch,
597
- session: initialSession,
598
- context,
599
- executeHook,
600
- generateMessage,
601
- schema,
602
- routeId,
603
- } = params;
604
-
605
- // Track timing for each phase (Requirement 11.1)
606
- const timing: BatchExecutionTiming = {
607
- totalMs: 0,
608
- };
609
- const batchStartTime = Date.now();
610
-
611
- // Track the last successful session state for error recovery
612
- let lastSuccessfulSession = initialSession;
613
- let currentSession = initialSession;
614
-
615
- // Track executed steps for the response
616
- const executedSteps: StepRef[] = [];
617
-
618
- // Log batch execution start with details (Requirement 11.1)
619
- logger.debug(`[BatchExecutor] Starting batch execution with ${batch.steps.length} steps, route: ${routeId || 'unknown'}`);
620
-
621
- // If batch is empty, return early with appropriate reason
622
- if (batch.steps.length === 0) {
623
- logger.debug(`[BatchExecutor] Empty batch, returning with stopped reason: ${batch.stoppedReason}`);
624
-
625
- // Emit batch_complete event for empty batch (Requirement 11.3)
626
- timing.totalMs = Date.now() - batchStartTime;
627
- this.emitBatchEvent('batch_complete', {
628
- batchSize: 0,
629
- stoppedReason: batch.stoppedReason,
630
- reason: 'Empty batch',
631
- timing,
632
- });
633
-
634
- return {
635
- message: '',
636
- session: currentSession,
637
- executedSteps: [],
638
- stoppedReason: batch.stoppedReason,
639
- collectedData: {},
640
- };
641
- }
642
-
643
- // PHASE 1: Execute prepare hooks (Requirement 5.4 - stop on failure)
644
- const prepareStartTime = Date.now();
645
- logger.debug(`[BatchExecutor] Phase 1: Executing prepare hooks`);
646
-
647
- const prepareResult = await this.executePrepareHooks({
648
- steps: batch.steps,
649
- context,
650
- data: currentSession.data,
651
- executeHook,
652
- });
653
-
654
- timing.prepareHooksMs = Date.now() - prepareStartTime;
655
- logger.debug(`[BatchExecutor] Prepare hooks completed in ${timing.prepareHooksMs}ms`);
656
-
657
- if (!prepareResult.success) {
658
- // Requirement 9.3: Preserve partial progress on errors
659
- // Requirement 2.4: Stop and include error information
660
- logger.error(`[BatchExecutor] Prepare hook failed:`, prepareResult.error);
661
-
662
- // Emit batch_complete event with error (Requirement 11.3)
663
- timing.totalMs = Date.now() - batchStartTime;
664
- this.emitBatchEvent('batch_complete', {
665
- batchSize: batch.steps.length,
666
- stoppedReason: 'prepare_error',
667
- reason: `Prepare hook failed: ${prepareResult.error?.message}`,
668
- timing,
669
- });
670
-
671
- return {
672
- message: '',
673
- session: lastSuccessfulSession, // Return last successful state
674
- executedSteps: prepareResult.executedSteps.map(stepId => ({
675
- id: stepId,
676
- routeId: routeId || 'unknown',
677
- })),
678
- stoppedReason: 'prepare_error',
679
- error: prepareResult.error,
680
- };
681
- }
682
-
683
- // Update last successful session after prepare hooks complete
684
- lastSuccessfulSession = currentSession;
685
-
686
- // PHASE 2: Make LLM call (Requirement 9.1 - preserve session state on failure)
687
- const llmStartTime = Date.now();
688
- logger.debug(`[BatchExecutor] Phase 2: Making LLM call`);
689
-
690
- let llmResponse: Record<string, unknown>;
691
- let message: string;
692
-
693
- try {
694
- const result = await generateMessage();
695
- llmResponse = result.structured || {};
696
- message = result.message || '';
697
-
698
- timing.llmCallMs = Date.now() - llmStartTime;
699
- logger.debug(`[BatchExecutor] LLM call successful in ${timing.llmCallMs}ms`);
700
- } catch (error) {
701
- // Requirement 9.1: Return error response with last successful session state
702
- const errorMessage = error instanceof Error ? error.message : String(error);
703
- timing.llmCallMs = Date.now() - llmStartTime;
704
- logger.error(`[BatchExecutor] LLM call failed after ${timing.llmCallMs}ms:`, errorMessage);
705
-
706
- // Emit batch_complete event with error (Requirement 11.3)
707
- timing.totalMs = Date.now() - batchStartTime;
708
- this.emitBatchEvent('batch_complete', {
709
- batchSize: batch.steps.length,
710
- stoppedReason: 'llm_error',
711
- reason: `LLM call failed: ${errorMessage}`,
712
- timing,
713
- });
714
-
715
- return {
716
- message: '',
717
- session: lastSuccessfulSession, // Preserve session state
718
- executedSteps: [], // No steps were fully executed
719
- stoppedReason: 'llm_error',
720
- error: {
721
- type: 'llm_call',
722
- message: errorMessage,
723
- details: error,
724
- },
725
- };
726
- }
727
-
728
- // Update last successful session after LLM call
729
- lastSuccessfulSession = currentSession;
730
-
731
- // PHASE 3: Collect and validate data (Requirement 9.2 - include validation errors)
732
- const collectStartTime = Date.now();
733
- logger.debug(`[BatchExecutor] Phase 3: Collecting and validating data`);
734
-
735
- const collectResult = this.collectBatchData({
736
- steps: batch.steps,
737
- llmResponse,
738
- session: currentSession,
739
- schema,
740
- });
741
-
742
- timing.dataCollectionMs = Date.now() - collectStartTime;
743
- logger.debug(`[BatchExecutor] Data collection completed in ${timing.dataCollectionMs}ms`);
744
-
745
- // Update session with collected data (even if validation failed)
746
- currentSession = collectResult.session;
747
-
748
- // Track collected data for response
749
- const collectedData = collectResult.collectedData;
750
-
751
- // Check for validation errors
752
- let validationError: BatchExecutionError | undefined;
753
- if (!collectResult.success && collectResult.validationErrors && collectResult.validationErrors.length > 0) {
754
- // Requirement 9.2: Include validation errors in response
755
- logger.warn(`[BatchExecutor] Data validation failed:`, collectResult.validationErrors);
756
-
757
- validationError = {
758
- type: 'data_validation',
759
- message: `Validation failed for ${collectResult.validationErrors.length} field(s): ${collectResult.validationErrors.map(e => e.field).join(', ')}`,
760
- details: collectResult.validationErrors,
761
- };
762
-
763
- // Note: We continue execution despite validation errors
764
- // The error is included in the response for the caller to handle
765
- }
766
-
767
- // Update last successful session after data collection
768
- // (even with validation errors, we preserve the collected data)
769
- lastSuccessfulSession = currentSession;
770
-
771
- // Build executed steps list
772
- for (const step of batch.steps) {
773
- if (step.id) {
774
- executedSteps.push({
775
- id: step.id,
776
- routeId: routeId || 'unknown',
777
- });
778
- }
779
- }
780
-
781
- // PHASE 4: Execute finalize hooks (Requirement 5.5 - continue on failure)
782
- const finalizeStartTime = Date.now();
783
- logger.debug(`[BatchExecutor] Phase 4: Executing finalize hooks`);
784
-
785
- const finalizeResult = await this.executeFinalizeHooks({
786
- steps: batch.steps,
787
- context,
788
- data: currentSession.data,
789
- executeHook,
790
- });
791
-
792
- timing.finalizeHooksMs = Date.now() - finalizeStartTime;
793
- logger.debug(`[BatchExecutor] Finalize hooks completed in ${timing.finalizeHooksMs}ms`);
794
-
795
- // Log finalize errors but don't fail the batch
796
- let finalizeError: BatchExecutionError | undefined;
797
- if (finalizeResult.errors && finalizeResult.errors.length > 0) {
798
- logger.warn(`[BatchExecutor] Some finalize hooks failed:`, finalizeResult.errors);
799
-
800
- // Create a summary error for finalize failures
801
- finalizeError = {
802
- type: 'finalize_hook',
803
- message: `${finalizeResult.errors.length} finalize hook(s) failed`,
804
- details: finalizeResult.errors,
805
- };
806
- }
807
-
808
- // Determine the final stopped reason
809
- // Priority: validation_error > finalize_error > batch.stoppedReason
810
- let finalStoppedReason: StoppedReason = batch.stoppedReason;
811
- let finalError: BatchExecutionError | undefined;
812
-
813
- if (validationError) {
814
- finalStoppedReason = 'validation_error';
815
- finalError = validationError;
816
- } else if (finalizeError) {
817
- // Finalize errors are non-fatal, so we keep the original stopped reason
818
- // but include the error in the response
819
- finalError = finalizeError;
820
- }
821
-
822
- // Calculate total time and log completion (Requirement 11.1, 11.2)
823
- timing.totalMs = Date.now() - batchStartTime;
824
- logger.debug(`[BatchExecutor] Batch execution complete. Stopped reason: ${finalStoppedReason}, Executed steps: ${executedSteps.length}, Total time: ${timing.totalMs}ms`);
825
-
826
- // Emit batch_complete event (Requirement 11.3)
827
- this.emitBatchEvent('batch_complete', {
828
- batchSize: executedSteps.length,
829
- stoppedReason: finalStoppedReason,
830
- reason: `Batch completed with ${executedSteps.length} steps`,
831
- timing,
832
- });
833
-
834
- return {
835
- message,
836
- session: currentSession,
837
- executedSteps,
838
- stoppedReason: finalStoppedReason,
839
- collectedData,
840
- error: finalError,
841
- };
842
- }
843
-
844
- /**
845
- * Collect data from LLM response for all steps in the batch
846
- *
847
- * This method:
848
- * 1. Gathers all collect fields from all steps in the batch
849
- * 2. Extracts those fields from the LLM response
850
- * 3. Validates extracted data against the agent schema (if provided)
851
- * 4. Updates session data with all collected values
852
- *
853
- * @param params - Parameters for data collection
854
- * @returns Result with collected data, updated session, and any validation errors
855
- *
856
- * **Validates: Requirements 6.1, 6.2, 6.3**
857
- */
858
- collectBatchData(params: CollectBatchDataParams<TData>): CollectBatchDataResult<TData> {
859
- const { steps, llmResponse, session, schema } = params;
860
-
861
- logger.debug(`[BatchExecutor] Collecting batch data from ${steps.length} steps`);
862
-
863
- // Requirement 6.1: Gather all collect fields from all steps in the batch
864
- const allCollectFields = new Set<string>();
865
- for (const step of steps) {
866
- if (step.collect && step.collect.length > 0) {
867
- for (const field of step.collect) {
868
- allCollectFields.add(String(field));
869
- }
870
- }
871
- }
872
-
873
- logger.debug(`[BatchExecutor] Collect fields to extract: ${Array.from(allCollectFields).join(', ')}`);
874
-
875
- // If no fields to collect, return early with unchanged session
876
- if (allCollectFields.size === 0) {
877
- logger.debug(`[BatchExecutor] No collect fields defined, skipping data collection`);
878
- return {
879
- success: true,
880
- collectedData: {},
881
- session,
882
- fieldsCollected: [],
883
- };
884
- }
885
-
886
- // Extract data from LLM response for all collect fields
887
- const collectedData: Partial<TData> = {};
888
- const fieldsCollected: string[] = [];
889
- const fieldsMissing: string[] = [];
890
-
891
- for (const field of allCollectFields) {
892
- // Check if the field exists in the LLM response
893
- if (field in llmResponse && llmResponse[field] !== undefined) {
894
- (collectedData as Record<string, unknown>)[field] = llmResponse[field];
895
- fieldsCollected.push(field);
896
- logger.debug(`[BatchExecutor] Collected field '${field}': ${JSON.stringify(llmResponse[field])}`);
897
- } else {
898
- fieldsMissing.push(field);
899
- logger.debug(`[BatchExecutor] Field '${field}' not found in LLM response`);
900
- }
901
- }
902
-
903
- // Requirement 6.2: Validate collected data against the agent schema
904
- const validationErrors: ValidationError[] = [];
905
-
906
- if (schema && Object.keys(collectedData).length > 0) {
907
- logger.debug(`[BatchExecutor] Validating collected data against schema`);
908
-
909
- const validationResult = this.validateAgainstSchema(collectedData, schema);
910
- if (!validationResult.valid) {
911
- validationErrors.push(...validationResult.errors);
912
- logger.warn(`[BatchExecutor] Schema validation found ${validationErrors.length} error(s)`);
913
- }
914
- }
915
-
916
- // Requirement 6.3: Update session data with all collected values
917
- // Only merge valid data (data that passed validation or had no schema to validate against)
918
- let updatedSession = session;
919
- if (Object.keys(collectedData).length > 0) {
920
- // Filter out fields with validation errors if we want strict validation
921
- // For now, we include all collected data and report errors separately
922
- updatedSession = mergeCollected(session, collectedData);
923
- logger.debug(`[BatchExecutor] Updated session with collected data`);
924
- }
925
-
926
- const success = validationErrors.length === 0;
927
-
928
- logger.debug(`[BatchExecutor] Data collection complete. Success: ${success}, Fields collected: ${fieldsCollected.length}, Fields missing: ${fieldsMissing.length}`);
929
-
930
- return {
931
- success,
932
- collectedData,
933
- session: updatedSession,
934
- fieldsCollected,
935
- fieldsMissing: fieldsMissing.length > 0 ? fieldsMissing : undefined,
936
- validationErrors: validationErrors.length > 0 ? validationErrors : undefined,
937
- };
938
- }
939
-
940
- /**
941
- * Validate data against a JSON schema
942
- *
943
- * Performs basic validation of collected data against the agent schema.
944
- * Checks:
945
- * - Fields exist in schema properties
946
- * - Required fields are present (as warnings)
947
- * - Basic type validation
948
- *
949
- * @param data - Data to validate
950
- * @param schema - JSON schema to validate against
951
- * @returns Validation result with errors
952
- * @private
953
- */
954
- private validateAgainstSchema(
955
- data: Partial<TData>,
956
- schema: StructuredSchema
957
- ): { valid: boolean; errors: ValidationError[] } {
958
- const errors: ValidationError[] = [];
959
-
960
- // Check if provided fields exist in schema
961
- if (schema.properties) {
962
- for (const [key, value] of Object.entries(data)) {
963
- if (!(key in schema.properties)) {
964
- errors.push({
965
- field: key,
966
- value,
967
- message: `Field '${key}' is not defined in schema`,
968
- schemaPath: `properties.${key}`,
969
- });
970
- } else {
971
- // Basic type validation
972
- const fieldSchema = schema.properties[key];
973
- const typeError = this.validateFieldType(key, value, fieldSchema);
974
- if (typeError) {
975
- errors.push(typeError);
976
- }
977
- }
978
- }
979
- }
980
-
981
- return {
982
- valid: errors.length === 0,
983
- errors,
984
- };
985
- }
986
-
987
- /**
988
- * Validate a single field's type against its schema
989
- * @private
990
- */
991
- private validateFieldType(
992
- field: string,
993
- value: unknown,
994
- fieldSchema: StructuredSchema
995
- ): ValidationError | null {
996
- if (value === null || value === undefined) {
997
- // Null/undefined values are handled separately (required field check)
998
- return null;
999
- }
1000
-
1001
- const expectedType = fieldSchema.type;
1002
- if (!expectedType) {
1003
- // No type specified, consider valid
1004
- return null;
1005
- }
1006
-
1007
- const actualType = Array.isArray(value) ? 'array' : typeof value;
1008
-
1009
- // Handle array of types
1010
- const allowedTypes = Array.isArray(expectedType) ? expectedType : [expectedType];
1011
-
1012
- // Map JavaScript types to JSON Schema types
1013
- const typeMapping: Record<string, string> = {
1014
- 'string': 'string',
1015
- 'number': 'number',
1016
- 'boolean': 'boolean',
1017
- 'object': 'object',
1018
- 'array': 'array',
1019
- };
1020
-
1021
- const mappedActualType = typeMapping[actualType] || actualType;
1022
-
1023
- // Check if actual type matches any allowed type
1024
- // Also handle 'integer' as a valid number type
1025
- const isValidType = allowedTypes.some(t => {
1026
- if (t === 'integer') {
1027
- return typeof value === 'number' && Number.isInteger(value);
1028
- }
1029
- return t === mappedActualType;
1030
- });
1031
-
1032
- if (!isValidType) {
1033
- return {
1034
- field,
1035
- value,
1036
- message: `Field '${field}' has type '${actualType}' but expected '${allowedTypes.join(' | ')}'`,
1037
- schemaPath: `properties.${field}.type`,
1038
- };
1039
- }
1040
-
1041
- return null;
1042
- }
1043
- }
1044
-
1045
- /**
1046
- * Parameters for executing hooks on batched steps
1047
- */
1048
- export interface ExecuteHooksParams<TContext, TData> {
1049
- /** Steps in the batch to execute hooks for */
1050
- steps: StepOptions<TContext, TData>[];
1051
- /** Agent context */
1052
- context: TContext;
1053
- /** Current session data */
1054
- data?: Partial<TData>;
1055
- /**
1056
- * Function to execute a single hook (prepare or finalize)
1057
- * This allows the caller to provide their own hook execution logic
1058
- * (e.g., using ToolManager for tool-based hooks)
1059
- */
1060
- executeHook: (
1061
- hook: HookFunction<TContext, TData>,
1062
- context: TContext,
1063
- data?: Partial<TData>,
1064
- step?: StepOptions<TContext, TData>
1065
- ) => Promise<void>;
1066
- }
1067
-
1068
- /**
1069
- * Type for the hook execution function
1070
- */
1071
- export type HookFunction<TContext, TData> =
1072
- | string
1073
- | Tool<TContext, TData>
1074
- | ((context: TContext, data?: Partial<TData>) => void | Promise<void>);
1075
-
1076
- /**
1077
- * Result of hook execution
1078
- */
1079
- export interface HookExecutionResult {
1080
- /** Whether all hooks executed successfully */
1081
- success: boolean;
1082
- /** IDs of steps whose hooks were executed */
1083
- executedSteps: string[];
1084
- /** Error details if a hook failed (for prepare hooks) */
1085
- error?: BatchExecutionError;
1086
- /** Array of errors for finalize hooks (which continue on failure) */
1087
- errors?: Array<{ stepId: string; error: BatchExecutionError }>;
1088
- }
1089
-
1090
- /**
1091
- * Hook executor interface for managing prepare/finalize phases
1092
- */
1093
- export interface HookExecutor<TContext, TData> {
1094
- /** Execute all prepare hooks */
1095
- executePrepare: () => Promise<HookExecutionResult>;
1096
- /** Execute all finalize hooks */
1097
- executeFinalize: () => Promise<HookExecutionResult>;
1098
- /** Execute a single hook (used internally) */
1099
- executeHook?: (
1100
- hook: HookFunction<TContext, TData>,
1101
- context: TContext,
1102
- data?: Partial<TData>,
1103
- step?: StepOptions<TContext, TData>
1104
- ) => Promise<void>;
1105
- }
1106
-
1107
- /**
1108
- * Parameters for collecting batch data from LLM response
1109
- */
1110
- export interface CollectBatchDataParams<TData> {
1111
- /** Steps in the batch that may have collect fields */
1112
- steps: Array<{ collect?: readonly (keyof TData)[] }>;
1113
- /** The LLM response containing collected data */
1114
- llmResponse: Record<string, unknown>;
1115
- /** Current session state to update */
1116
- session: SessionState<TData>;
1117
- /** Optional agent schema for validation */
1118
- schema?: StructuredSchema;
1119
- }
1120
-
1121
- /**
1122
- * Result of batch data collection
1123
- */
1124
- export interface CollectBatchDataResult<TData> {
1125
- /** Whether data collection and validation succeeded */
1126
- success: boolean;
1127
- /** Data collected from the LLM response */
1128
- collectedData: Partial<TData>;
1129
- /** Updated session with collected data merged */
1130
- session: SessionState<TData>;
1131
- /** Fields that were successfully collected */
1132
- fieldsCollected: string[];
1133
- /** Fields that were expected but not found in response */
1134
- fieldsMissing?: string[];
1135
- /** Validation errors if schema validation failed */
1136
- validationErrors?: ValidationError[];
1137
- }
1138
-
1139
- /**
1140
- * Validation error for schema validation
1141
- */
1142
- export interface ValidationError {
1143
- /** Field that failed validation */
1144
- field: string;
1145
- /** Value that failed validation */
1146
- value: unknown;
1147
- /** Error message */
1148
- message: string;
1149
- /** Path in schema where validation failed */
1150
- schemaPath: string;
1151
- }
1152
-
1153
-
1154
- /**
1155
- * Parameters for executing a batch of steps
1156
- */
1157
- export interface ExecuteBatchParams<TContext, TData> {
1158
- /** The batch result from determineBatch */
1159
- batch: BatchResult<TContext, TData>;
1160
- /** Current session state */
1161
- session: SessionState<TData>;
1162
- /** Agent context */
1163
- context: TContext;
1164
- /**
1165
- * Function to execute a single hook (prepare or finalize)
1166
- * This allows the caller to provide their own hook execution logic
1167
- */
1168
- executeHook: (
1169
- hook: HookFunction<TContext, TData>,
1170
- context: TContext,
1171
- data?: Partial<TData>,
1172
- step?: StepOptions<TContext, TData>
1173
- ) => Promise<void>;
1174
- /**
1175
- * Function to generate the LLM message
1176
- * This allows the caller to provide their own LLM call logic
1177
- * (e.g., using BatchPromptBuilder and AI provider)
1178
- */
1179
- generateMessage: () => Promise<{
1180
- message: string;
1181
- structured?: Record<string, unknown>;
1182
- }>;
1183
- /** Optional agent schema for validation */
1184
- schema?: StructuredSchema;
1185
- /** Route ID for step references */
1186
- routeId?: string;
1187
- }