@falai/agent 1.2.8 → 2.0.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 (522) 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 +1191 -1014
  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 +509 -136
  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/AnthropicProvider.d.ts +1 -1
  126. package/dist/cjs/providers/AnthropicProvider.js +1 -1
  127. package/dist/cjs/providers/GeminiProvider.d.ts +1 -1
  128. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  129. package/dist/cjs/providers/GeminiProvider.js +1 -1
  130. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  131. package/dist/cjs/providers/OpenAIProvider.d.ts +1 -1
  132. package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
  133. package/dist/cjs/providers/OpenAIProvider.js +1 -1
  134. package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
  135. package/dist/cjs/types/agent.d.ts +183 -54
  136. package/dist/cjs/types/agent.d.ts.map +1 -1
  137. package/dist/cjs/types/agent.js +0 -6
  138. package/dist/cjs/types/agent.js.map +1 -1
  139. package/dist/cjs/types/ai.d.ts +3 -3
  140. package/dist/cjs/types/ai.d.ts.map +1 -1
  141. package/dist/cjs/types/errors.d.ts +15 -0
  142. package/dist/cjs/types/errors.d.ts.map +1 -0
  143. package/dist/cjs/types/errors.js +22 -0
  144. package/dist/cjs/types/errors.js.map +1 -0
  145. package/dist/cjs/types/flow.d.ts +513 -0
  146. package/dist/cjs/types/flow.d.ts.map +1 -0
  147. package/dist/cjs/types/{route.js → flow.js} +2 -2
  148. package/dist/cjs/types/flow.js.map +1 -0
  149. package/dist/cjs/types/index.d.ts +7 -6
  150. package/dist/cjs/types/index.d.ts.map +1 -1
  151. package/dist/cjs/types/index.js +6 -2
  152. package/dist/cjs/types/index.js.map +1 -1
  153. package/dist/cjs/types/persistence.d.ts +11 -7
  154. package/dist/cjs/types/persistence.d.ts.map +1 -1
  155. package/dist/cjs/types/routing.d.ts +1 -1
  156. package/dist/cjs/types/routing.d.ts.map +1 -1
  157. package/dist/cjs/types/session.d.ts +24 -23
  158. package/dist/cjs/types/session.d.ts.map +1 -1
  159. package/dist/cjs/types/signals.d.ts +248 -0
  160. package/dist/cjs/types/signals.d.ts.map +1 -0
  161. package/dist/cjs/types/signals.js +11 -0
  162. package/dist/cjs/types/signals.js.map +1 -0
  163. package/dist/cjs/types/template.d.ts +2 -8
  164. package/dist/cjs/types/template.d.ts.map +1 -1
  165. package/dist/cjs/types/tool.d.ts +36 -29
  166. package/dist/cjs/types/tool.d.ts.map +1 -1
  167. package/dist/cjs/types/tool.js +1 -1
  168. package/dist/cjs/types/tool.js.map +1 -1
  169. package/dist/cjs/utils/condition.d.ts +7 -1
  170. package/dist/cjs/utils/condition.d.ts.map +1 -1
  171. package/dist/cjs/utils/condition.js.map +1 -1
  172. package/dist/cjs/utils/id.d.ts +13 -5
  173. package/dist/cjs/utils/id.d.ts.map +1 -1
  174. package/dist/cjs/utils/id.js +24 -10
  175. package/dist/cjs/utils/id.js.map +1 -1
  176. package/dist/cjs/utils/index.d.ts +2 -2
  177. package/dist/cjs/utils/index.d.ts.map +1 -1
  178. package/dist/cjs/utils/index.js +7 -3
  179. package/dist/cjs/utils/index.js.map +1 -1
  180. package/dist/cjs/utils/session.d.ts +44 -5
  181. package/dist/cjs/utils/session.d.ts.map +1 -1
  182. package/dist/cjs/utils/session.js +197 -38
  183. package/dist/cjs/utils/session.js.map +1 -1
  184. package/dist/constants/index.d.ts +0 -9
  185. package/dist/constants/index.d.ts.map +1 -1
  186. package/dist/constants/index.js +3 -9
  187. package/dist/constants/index.js.map +1 -1
  188. package/dist/core/Agent.d.ts +119 -153
  189. package/dist/core/Agent.d.ts.map +1 -1
  190. package/dist/core/Agent.js +472 -325
  191. package/dist/core/Agent.js.map +1 -1
  192. package/dist/core/AutoChainExecutor.d.ts +107 -0
  193. package/dist/core/AutoChainExecutor.d.ts.map +1 -0
  194. package/dist/core/AutoChainExecutor.js +293 -0
  195. package/dist/core/AutoChainExecutor.js.map +1 -0
  196. package/dist/core/BranchEvaluator.d.ts +54 -0
  197. package/dist/core/BranchEvaluator.d.ts.map +1 -0
  198. package/dist/core/BranchEvaluator.js +126 -0
  199. package/dist/core/BranchEvaluator.js.map +1 -0
  200. package/dist/core/DirectiveBus.d.ts +88 -0
  201. package/dist/core/DirectiveBus.d.ts.map +1 -0
  202. package/dist/core/DirectiveBus.js +192 -0
  203. package/dist/core/DirectiveBus.js.map +1 -0
  204. package/dist/core/DirectiveChainTracker.d.ts +49 -0
  205. package/dist/core/DirectiveChainTracker.d.ts.map +1 -0
  206. package/dist/core/DirectiveChainTracker.js +117 -0
  207. package/dist/core/DirectiveChainTracker.js.map +1 -0
  208. package/dist/core/Flow.d.ts +186 -0
  209. package/dist/core/Flow.d.ts.map +1 -0
  210. package/dist/core/Flow.js +546 -0
  211. package/dist/core/Flow.js.map +1 -0
  212. package/dist/core/FlowRouter.d.ts +182 -0
  213. package/dist/core/FlowRouter.d.ts.map +1 -0
  214. package/dist/core/{RoutingEngine.js → FlowRouter.js} +322 -305
  215. package/dist/core/FlowRouter.js.map +1 -0
  216. package/dist/core/PersistenceManager.d.ts +2 -2
  217. package/dist/core/PersistenceManager.d.ts.map +1 -1
  218. package/dist/core/PersistenceManager.js +7 -7
  219. package/dist/core/PersistenceManager.js.map +1 -1
  220. package/dist/core/PromptComposer.d.ts +21 -8
  221. package/dist/core/PromptComposer.d.ts.map +1 -1
  222. package/dist/core/PromptComposer.js +183 -106
  223. package/dist/core/PromptComposer.js.map +1 -1
  224. package/dist/core/PromptSectionCache.d.ts +1 -1
  225. package/dist/core/PromptSectionCache.js +1 -1
  226. package/dist/core/ResponseEngine.d.ts +18 -8
  227. package/dist/core/ResponseEngine.d.ts.map +1 -1
  228. package/dist/core/ResponseEngine.js +38 -36
  229. package/dist/core/ResponseEngine.js.map +1 -1
  230. package/dist/core/ResponseModal.d.ts +73 -56
  231. package/dist/core/ResponseModal.d.ts.map +1 -1
  232. package/dist/core/ResponseModal.js +1193 -1016
  233. package/dist/core/ResponseModal.js.map +1 -1
  234. package/dist/core/ResponsePipeline.d.ts +124 -26
  235. package/dist/core/ResponsePipeline.d.ts.map +1 -1
  236. package/dist/core/ResponsePipeline.js +509 -137
  237. package/dist/core/ResponsePipeline.js.map +1 -1
  238. package/dist/core/SignalEvaluator.d.ts +86 -0
  239. package/dist/core/SignalEvaluator.d.ts.map +1 -0
  240. package/dist/core/SignalEvaluator.js +326 -0
  241. package/dist/core/SignalEvaluator.js.map +1 -0
  242. package/dist/core/SignalProcessor.d.ts +152 -0
  243. package/dist/core/SignalProcessor.d.ts.map +1 -0
  244. package/dist/core/SignalProcessor.js +555 -0
  245. package/dist/core/SignalProcessor.js.map +1 -0
  246. package/dist/core/Step.d.ts +43 -32
  247. package/dist/core/Step.d.ts.map +1 -1
  248. package/dist/core/Step.js +220 -126
  249. package/dist/core/Step.js.map +1 -1
  250. package/dist/core/StreamingToolExecutor.d.ts +2 -2
  251. package/dist/core/StreamingToolExecutor.d.ts.map +1 -1
  252. package/dist/core/StreamingToolExecutor.js.map +1 -1
  253. package/dist/core/ToolManager.d.ts +44 -13
  254. package/dist/core/ToolManager.d.ts.map +1 -1
  255. package/dist/core/ToolManager.js +174 -91
  256. package/dist/core/ToolManager.js.map +1 -1
  257. package/dist/core/createAgent.d.ts +35 -0
  258. package/dist/core/createAgent.d.ts.map +1 -0
  259. package/dist/core/createAgent.js +36 -0
  260. package/dist/core/createAgent.js.map +1 -0
  261. package/dist/core/flow-namespace.d.ts +49 -0
  262. package/dist/core/flow-namespace.d.ts.map +1 -0
  263. package/dist/core/flow-namespace.js +168 -0
  264. package/dist/core/flow-namespace.js.map +1 -0
  265. package/dist/index.d.ts +11 -14
  266. package/dist/index.d.ts.map +1 -1
  267. package/dist/index.js +9 -12
  268. package/dist/index.js.map +1 -1
  269. package/dist/providers/AnthropicProvider.d.ts +1 -1
  270. package/dist/providers/AnthropicProvider.js +1 -1
  271. package/dist/providers/GeminiProvider.d.ts +1 -1
  272. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  273. package/dist/providers/GeminiProvider.js +1 -1
  274. package/dist/providers/GeminiProvider.js.map +1 -1
  275. package/dist/providers/OpenAIProvider.d.ts +1 -1
  276. package/dist/providers/OpenAIProvider.d.ts.map +1 -1
  277. package/dist/providers/OpenAIProvider.js +1 -1
  278. package/dist/providers/OpenAIProvider.js.map +1 -1
  279. package/dist/types/agent.d.ts +183 -54
  280. package/dist/types/agent.d.ts.map +1 -1
  281. package/dist/types/agent.js +0 -6
  282. package/dist/types/agent.js.map +1 -1
  283. package/dist/types/ai.d.ts +3 -3
  284. package/dist/types/ai.d.ts.map +1 -1
  285. package/dist/types/errors.d.ts +15 -0
  286. package/dist/types/errors.d.ts.map +1 -0
  287. package/dist/types/errors.js +18 -0
  288. package/dist/types/errors.js.map +1 -0
  289. package/dist/types/flow.d.ts +513 -0
  290. package/dist/types/flow.d.ts.map +1 -0
  291. package/dist/types/flow.js +5 -0
  292. package/dist/types/flow.js.map +1 -0
  293. package/dist/types/index.d.ts +7 -6
  294. package/dist/types/index.d.ts.map +1 -1
  295. package/dist/types/index.js +4 -1
  296. package/dist/types/index.js.map +1 -1
  297. package/dist/types/persistence.d.ts +11 -7
  298. package/dist/types/persistence.d.ts.map +1 -1
  299. package/dist/types/routing.d.ts +1 -1
  300. package/dist/types/routing.d.ts.map +1 -1
  301. package/dist/types/session.d.ts +24 -23
  302. package/dist/types/session.d.ts.map +1 -1
  303. package/dist/types/signals.d.ts +248 -0
  304. package/dist/types/signals.d.ts.map +1 -0
  305. package/dist/types/signals.js +10 -0
  306. package/dist/types/signals.js.map +1 -0
  307. package/dist/types/template.d.ts +2 -8
  308. package/dist/types/template.d.ts.map +1 -1
  309. package/dist/types/tool.d.ts +36 -29
  310. package/dist/types/tool.d.ts.map +1 -1
  311. package/dist/types/tool.js +1 -1
  312. package/dist/types/tool.js.map +1 -1
  313. package/dist/utils/condition.d.ts +7 -1
  314. package/dist/utils/condition.d.ts.map +1 -1
  315. package/dist/utils/condition.js.map +1 -1
  316. package/dist/utils/id.d.ts +13 -5
  317. package/dist/utils/id.d.ts.map +1 -1
  318. package/dist/utils/id.js +22 -9
  319. package/dist/utils/id.js.map +1 -1
  320. package/dist/utils/index.d.ts +2 -2
  321. package/dist/utils/index.d.ts.map +1 -1
  322. package/dist/utils/index.js +2 -2
  323. package/dist/utils/index.js.map +1 -1
  324. package/dist/utils/session.d.ts +44 -5
  325. package/dist/utils/session.d.ts.map +1 -1
  326. package/dist/utils/session.js +193 -37
  327. package/dist/utils/session.js.map +1 -1
  328. package/docs/README.md +22 -200
  329. package/docs/concepts/architecture.md +281 -0
  330. package/docs/concepts/directives.md +400 -0
  331. package/docs/concepts/pipeline.md +399 -0
  332. package/docs/guides/branching.md +263 -0
  333. package/docs/guides/compaction.md +163 -0
  334. package/docs/guides/conditions.md +167 -0
  335. package/docs/guides/error-handling.md +176 -0
  336. package/docs/guides/flow-control.md +409 -0
  337. package/docs/guides/instructions.md +210 -0
  338. package/docs/guides/persistence.md +182 -0
  339. package/docs/guides/streaming.md +137 -0
  340. package/docs/migration/README.md +14 -0
  341. package/docs/migration/route-to-flow.md +561 -0
  342. package/docs/migration/v1-to-v2.md +909 -0
  343. package/docs/reference/adapters.md +481 -0
  344. package/docs/reference/branches.md +241 -0
  345. package/docs/reference/create-agent.md +186 -0
  346. package/docs/reference/directive.md +243 -0
  347. package/docs/reference/errors.md +122 -0
  348. package/docs/reference/flow.md +238 -0
  349. package/docs/reference/instruction.md +177 -0
  350. package/docs/reference/pre-directive.md +131 -0
  351. package/docs/reference/providers.md +227 -0
  352. package/docs/reference/signals.md +356 -0
  353. package/docs/reference/step.md +339 -0
  354. package/docs/reference/tool.md +269 -0
  355. package/docs/start/01-install.md +81 -0
  356. package/docs/start/02-first-agent.md +196 -0
  357. package/docs/start/03-collect-data.md +222 -0
  358. package/docs/start/04-add-tools.md +276 -0
  359. package/docs/start/05-go-to-production.md +216 -0
  360. package/examples/01-quickstart.ts +20 -0
  361. package/examples/02-data-extraction.ts +90 -0
  362. package/examples/03-tools.ts +136 -0
  363. package/examples/04-instructions.ts +100 -0
  364. package/examples/05-branching.ts +140 -0
  365. package/examples/06-flow-control.ts +103 -0
  366. package/examples/07-streaming.ts +69 -0
  367. package/examples/08-persistence.ts +98 -0
  368. package/examples/09-signals.ts +144 -0
  369. package/examples/tsconfig.json +30 -0
  370. package/package.json +2 -1
  371. package/src/adapters/MemoryAdapter.ts +3 -3
  372. package/src/adapters/MongoAdapter.ts +3 -3
  373. package/src/adapters/OpenSearchAdapter.ts +10 -8
  374. package/src/adapters/PostgreSQLAdapter.ts +26 -10
  375. package/src/adapters/PrismaAdapter.ts +6 -6
  376. package/src/adapters/RedisAdapter.ts +3 -3
  377. package/src/adapters/SQLiteAdapter.ts +31 -12
  378. package/src/constants/index.ts +2 -10
  379. package/src/core/Agent.ts +585 -374
  380. package/src/core/AutoChainExecutor.ts +440 -0
  381. package/src/core/BranchEvaluator.ts +167 -0
  382. package/src/core/DirectiveBus.ts +248 -0
  383. package/src/core/DirectiveChainTracker.ts +144 -0
  384. package/src/core/Flow.ts +666 -0
  385. package/src/core/{RoutingEngine.ts → FlowRouter.ts} +385 -365
  386. package/src/core/PersistenceManager.ts +8 -8
  387. package/src/core/PromptComposer.ts +209 -140
  388. package/src/core/PromptSectionCache.ts +1 -1
  389. package/src/core/ResponseEngine.ts +61 -46
  390. package/src/core/ResponseModal.ts +1453 -1240
  391. package/src/core/ResponsePipeline.ts +655 -175
  392. package/src/core/SignalEvaluator.ts +420 -0
  393. package/src/core/SignalProcessor.ts +723 -0
  394. package/src/core/Step.ts +279 -176
  395. package/src/core/StreamingToolExecutor.ts +4 -4
  396. package/src/core/ToolManager.ts +200 -97
  397. package/src/core/createAgent.ts +40 -0
  398. package/src/core/flow-namespace.ts +219 -0
  399. package/src/index.ts +42 -36
  400. package/src/providers/AnthropicProvider.ts +2 -2
  401. package/src/providers/GeminiProvider.ts +2 -2
  402. package/src/providers/OpenAIProvider.ts +2 -2
  403. package/src/types/agent.ts +182 -53
  404. package/src/types/ai.ts +3 -3
  405. package/src/types/errors.ts +18 -0
  406. package/src/types/flow.ts +590 -0
  407. package/src/types/index.ts +43 -16
  408. package/src/types/persistence.ts +12 -8
  409. package/src/types/routing.ts +1 -1
  410. package/src/types/session.ts +26 -23
  411. package/src/types/signals.ts +321 -0
  412. package/src/types/template.ts +3 -11
  413. package/src/types/tool.ts +50 -42
  414. package/src/utils/condition.ts +13 -4
  415. package/src/utils/id.ts +27 -9
  416. package/src/utils/index.ts +6 -2
  417. package/src/utils/session.ts +238 -42
  418. package/dist/cjs/core/BatchExecutor.d.ts +0 -359
  419. package/dist/cjs/core/BatchExecutor.d.ts.map +0 -1
  420. package/dist/cjs/core/BatchExecutor.js +0 -861
  421. package/dist/cjs/core/BatchExecutor.js.map +0 -1
  422. package/dist/cjs/core/BatchPromptBuilder.d.ts +0 -89
  423. package/dist/cjs/core/BatchPromptBuilder.d.ts.map +0 -1
  424. package/dist/cjs/core/BatchPromptBuilder.js +0 -223
  425. package/dist/cjs/core/BatchPromptBuilder.js.map +0 -1
  426. package/dist/cjs/core/Route.d.ts +0 -180
  427. package/dist/cjs/core/Route.d.ts.map +0 -1
  428. package/dist/cjs/core/Route.js +0 -542
  429. package/dist/cjs/core/Route.js.map +0 -1
  430. package/dist/cjs/core/RoutingEngine.d.ts +0 -185
  431. package/dist/cjs/core/RoutingEngine.d.ts.map +0 -1
  432. package/dist/cjs/core/RoutingEngine.js.map +0 -1
  433. package/dist/cjs/types/route.d.ts +0 -336
  434. package/dist/cjs/types/route.d.ts.map +0 -1
  435. package/dist/cjs/types/route.js.map +0 -1
  436. package/dist/core/BatchExecutor.d.ts +0 -359
  437. package/dist/core/BatchExecutor.d.ts.map +0 -1
  438. package/dist/core/BatchExecutor.js +0 -856
  439. package/dist/core/BatchExecutor.js.map +0 -1
  440. package/dist/core/BatchPromptBuilder.d.ts +0 -89
  441. package/dist/core/BatchPromptBuilder.d.ts.map +0 -1
  442. package/dist/core/BatchPromptBuilder.js +0 -219
  443. package/dist/core/BatchPromptBuilder.js.map +0 -1
  444. package/dist/core/Route.d.ts +0 -180
  445. package/dist/core/Route.d.ts.map +0 -1
  446. package/dist/core/Route.js +0 -538
  447. package/dist/core/Route.js.map +0 -1
  448. package/dist/core/RoutingEngine.d.ts +0 -185
  449. package/dist/core/RoutingEngine.d.ts.map +0 -1
  450. package/dist/core/RoutingEngine.js.map +0 -1
  451. package/dist/types/route.d.ts +0 -336
  452. package/dist/types/route.d.ts.map +0 -1
  453. package/dist/types/route.js +0 -5
  454. package/dist/types/route.js.map +0 -1
  455. package/docs/CONTRIBUTING.md +0 -521
  456. package/docs/api/README.md +0 -3299
  457. package/docs/api/overview.md +0 -1410
  458. package/docs/architecture/data-extraction-flow.md +0 -360
  459. package/docs/architecture/multi-step-execution.md +0 -277
  460. package/docs/core/agent/README.md +0 -938
  461. package/docs/core/agent/context-management.md +0 -796
  462. package/docs/core/agent/rules-and-prohibitions.md +0 -113
  463. package/docs/core/agent/session-management.md +0 -693
  464. package/docs/core/ai-integration/prompt-composition.md +0 -355
  465. package/docs/core/ai-integration/providers.md +0 -515
  466. package/docs/core/ai-integration/response-processing.md +0 -433
  467. package/docs/core/conversation-flows/data-collection.md +0 -772
  468. package/docs/core/conversation-flows/route-dsl.md +0 -509
  469. package/docs/core/conversation-flows/routes.md +0 -249
  470. package/docs/core/conversation-flows/step-transitions.md +0 -731
  471. package/docs/core/conversation-flows/steps.md +0 -268
  472. package/docs/core/error-handling.md +0 -830
  473. package/docs/core/persistence/adapters.md +0 -255
  474. package/docs/core/persistence/session-storage.md +0 -656
  475. package/docs/core/routing/intelligent-routing.md +0 -470
  476. package/docs/core/tools/enhanced-tool.md +0 -186
  477. package/docs/core/tools/streaming-execution.md +0 -161
  478. package/docs/core/tools/tool-definition.md +0 -970
  479. package/docs/core/tools/tool-scoping.md +0 -819
  480. package/docs/guides/advanced-patterns/publishing.md +0 -186
  481. package/docs/guides/context-compaction.md +0 -96
  482. package/docs/guides/error-handling-patterns.md +0 -578
  483. package/docs/guides/getting-started/README.md +0 -795
  484. package/docs/guides/migration/README.md +0 -101
  485. package/docs/guides/migration/flexible-routing-conditions.md +0 -375
  486. package/docs/guides/migration/multi-step-execution.md +0 -393
  487. package/docs/guides/migration/response-modal-refactor.md +0 -518
  488. package/docs/guides/prompt-optimization.md +0 -164
  489. package/examples/advanced-patterns/context-compaction.ts +0 -223
  490. package/examples/advanced-patterns/knowledge-based-agent.ts +0 -735
  491. package/examples/advanced-patterns/persistent-onboarding.ts +0 -728
  492. package/examples/advanced-patterns/route-lifecycle-hooks.ts +0 -556
  493. package/examples/advanced-patterns/streaming-responses.ts +0 -656
  494. package/examples/ai-providers/anthropic-integration.ts +0 -388
  495. package/examples/ai-providers/openai-integration.ts +0 -228
  496. package/examples/condition-patterns/function-only-conditions.ts +0 -365
  497. package/examples/condition-patterns/mixed-array-conditions.ts +0 -477
  498. package/examples/condition-patterns/route-skipif-patterns.ts +0 -468
  499. package/examples/condition-patterns/step-skipif-patterns.ts +0 -0
  500. package/examples/condition-patterns/string-only-conditions.ts +0 -296
  501. package/examples/conversation-flows/completion-transitions.ts +0 -318
  502. package/examples/core-concepts/basic-agent.ts +0 -503
  503. package/examples/core-concepts/modern-streaming-api.ts +0 -309
  504. package/examples/core-concepts/schema-driven-extraction.ts +0 -332
  505. package/examples/core-concepts/session-management.ts +0 -494
  506. package/examples/integrations/database-integration.ts +0 -631
  507. package/examples/integrations/healthcare-integration.ts +0 -595
  508. package/examples/integrations/search-integration.ts +0 -530
  509. package/examples/integrations/server-session-management.ts +0 -307
  510. package/examples/persistence/custom-adapter.ts +0 -526
  511. package/examples/persistence/database-persistence.ts +0 -583
  512. package/examples/persistence/memory-sessions.ts +0 -495
  513. package/examples/persistence/prisma-schema.example.prisma +0 -74
  514. package/examples/persistence/redis-persistence.ts +0 -488
  515. package/examples/tools/basic-tools.ts +0 -765
  516. package/examples/tools/data-enrichment-tools.ts +0 -593
  517. package/examples/tools/enhanced-tool-metadata.ts +0 -268
  518. package/examples/tools/streaming-tool-execution.ts +0 -283
  519. package/src/core/BatchExecutor.ts +0 -1187
  520. package/src/core/BatchPromptBuilder.ts +0 -299
  521. package/src/core/Route.ts +0 -678
  522. package/src/types/route.ts +0 -392
@@ -1,22 +1,120 @@
1
1
  /**
2
2
  * Response processing utilities shared between respond() and respondStream() methods
3
3
  */
4
- import { createSession, enterRoute, enterStep, mergeCollected, logger, render, historyToEvents, serializeToolResult, } from "../utils";
4
+ import { createSession, enterStep, mergeCollected, completeCurrentFlow, logger, historyToEvents, serializeToolResult, } from "../utils";
5
+ import { enterFlow } from "../utils/session";
5
6
  import { createTemplateContext } from "../utils/template";
6
- import { END_ROUTE_ID } from "../constants";
7
+ import { FlowConfigurationError } from "../core/Step";
8
+ import { evaluateBranches, createAiConditionEvaluator } from "./BranchEvaluator";
9
+ import { DirectiveChainTracker } from "./DirectiveChainTracker";
10
+ import { DirectiveBus } from "./DirectiveBus";
11
+ /**
12
+ * Position fields on a Directive that represent a navigation decision.
13
+ * When any of these is set, the directive "wins" the turn's position decision
14
+ * and downstream resolution (branches, linear, AI) must not run.
15
+ */
16
+ const DIRECTIVE_POSITION_FIELDS = ['goTo', 'goToStep', 'complete', 'abort', 'reset'];
17
+ /**
18
+ * Returns `true` if the given directive has at least one position field set.
19
+ * Used as the guard at the directive-bus / branch-evaluation seam:
20
+ * if the bus produced a winner with a position field, `evaluateStepBranches`
21
+ * (and linear/AI selection) must not run.
22
+ */
23
+ export function hasDirectivePositionField(directive) {
24
+ if (!directive)
25
+ return false;
26
+ return DIRECTIVE_POSITION_FIELDS.some((field) => directive[field] !== undefined);
27
+ }
7
28
  /**
8
29
  * Shared response processing logic between respond() and respondStream() methods
9
30
  */
10
31
  export class ResponsePipeline {
11
- constructor(options, getRoutes, tools, routingEngine, updateContext, updateData, updateCollectedData, toolManager) {
32
+ constructor(options, getFlows, tools, flowRouter, updateContext, updateData, updateCollectedData, toolManager, signalProcessor) {
12
33
  this.options = options;
13
- this.getRoutes = getRoutes;
34
+ this.getFlows = getFlows;
14
35
  this.tools = tools;
15
- this.routingEngine = routingEngine;
36
+ this.flowRouter = flowRouter;
16
37
  this.updateContext = updateContext;
17
38
  this.updateData = updateData;
18
39
  this.updateCollectedData = updateCollectedData;
19
40
  this.toolManager = toolManager;
41
+ this.signalProcessor = signalProcessor;
42
+ }
43
+ /**
44
+ * Create a fresh chain tracker for the current turn.
45
+ * Call at the start of each turn; the tracker is discarded at turn end.
46
+ */
47
+ createChainTracker() {
48
+ const maxChain = this.options.maxDirectiveChain ?? 10;
49
+ this._chainTracker = new DirectiveChainTracker(maxChain);
50
+ return this._chainTracker;
51
+ }
52
+ /**
53
+ * Get the current turn's chain tracker (creates one if none exists).
54
+ */
55
+ get chainTracker() {
56
+ if (!this._chainTracker) {
57
+ return this.createChainTracker();
58
+ }
59
+ return this._chainTracker;
60
+ }
61
+ /**
62
+ * Create a fresh DirectiveBus for a new turn.
63
+ * The bus collects directives from hooks, tools, and branches during the turn
64
+ * and merges them at phase boundaries via Algorithm 4.
65
+ */
66
+ createDirectiveBus() {
67
+ return new DirectiveBus();
68
+ }
69
+ // ──────────────────────────────────────────────────────────────────────────
70
+ // Signal pipeline phases
71
+ // ──────────────────────────────────────────────────────────────────────────
72
+ /**
73
+ * PRE-SIGNAL PHASE — Evaluates pre/both signals in parallel with routing.
74
+ *
75
+ * Delegates to `signalProcessor.runPreSignalPhase(...)` when configured.
76
+ * When no signal processor is present (zero-cost path), returns a stable
77
+ * empty shape so callers don't need to branch.
78
+ *
79
+ * @requirements 2.1, 2.3, 8.6, 13.3
80
+ */
81
+ async runPreSignalPhase(session, context, history) {
82
+ if (!this.signalProcessor) {
83
+ return { firings: [], updatedSession: session, mergedDirective: undefined };
84
+ }
85
+ const result = await this.signalProcessor.runPreSignalPhase({ session, history, context });
86
+ return {
87
+ firings: result.firings,
88
+ updatedSession: result.updatedSession,
89
+ mergedDirective: result.mergedDirective,
90
+ };
91
+ }
92
+ /**
93
+ * POST-SIGNAL PHASE — Evaluates post/both signals after finalize/onComplete.
94
+ *
95
+ * Delegates to `signalProcessor.runPostSignalPhase(...)` when configured.
96
+ * When no signal processor is present, returns a stable empty shape.
97
+ *
98
+ * Post-phase signals see the complete turn result: assistant message in history,
99
+ * collected data, tool results. Position directives from this phase set
100
+ * `session.pendingDirective` (no mid-turn re-entry per D6 decision).
101
+ *
102
+ * Pre-LLM-only fields (`appendPrompt`, `injectTools`, `halt`) are already
103
+ * dropped inside `runPostSignalPhase` per Phase 4.5 — this seam does NOT
104
+ * re-introduce them.
105
+ *
106
+ * @requirements 9.1, 9.2, 9.3, 9.4
107
+ */
108
+ async runPostSignalPhase(session, context, history) {
109
+ if (!this.signalProcessor) {
110
+ return { firings: [], updatedSession: session, mergedDirective: undefined };
111
+ }
112
+ const result = await this.signalProcessor.runPostSignalPhase({ session, history, context });
113
+ return {
114
+ firings: result.firings,
115
+ updatedSession: result.updatedSession,
116
+ mergedDirective: result.mergedDirective,
117
+ };
20
118
  }
21
119
  /**
22
120
  * Prepare context and session for response generation
@@ -48,45 +146,136 @@ export class ResponsePipeline {
48
146
  */
49
147
  async handleRoutingAndStepSelection(params) {
50
148
  const { session, history, context, signal } = params;
51
- // PHASE 2: ROUTING + STEP SELECTION - Determine which route and step to use (combined)
52
- let selectedRoute;
149
+ // PHASE 2: ROUTING + STEP SELECTION - Determine which flow and step to use (combined)
150
+ let selectedFlow;
53
151
  let responseDirectives;
54
152
  let selectedStep;
55
- let isRouteComplete = false;
56
- let completedRoutes = [];
153
+ let isFlowComplete = false;
154
+ let completedFlows = [];
57
155
  let targetSession = session;
58
- // Get routes early since we need them for pending transitions
59
- const routes = this.getRoutes();
60
- // Check for pending transition from previous route completion
61
- if (targetSession.pendingTransition) {
62
- const targetRoute = routes.find((r) => r.id === targetSession.pendingTransition?.targetRouteId);
63
- if (targetRoute) {
64
- logger.debug(`[ResponseHandler] Auto-transitioning from pending transition to route: ${targetRoute.title}`);
65
- // Clear pending transition and enter new route
66
- targetSession = {
67
- ...targetSession,
68
- pendingTransition: undefined,
69
- };
70
- targetSession = enterRoute(targetSession, targetRoute.id, targetRoute.title);
71
- // Merge initial data if available
72
- if (targetRoute.initialData) {
73
- targetSession = mergeCollected(targetSession, targetRoute.initialData);
156
+ // Get flows early since we need them for pending directives
157
+ const flows = this.getFlows();
158
+ // Check for pending directive from previous flow completion or external dispatch
159
+ if (targetSession.pendingDirective) {
160
+ const directive = targetSession.pendingDirective;
161
+ logger.debug(`[ResponseHandler] Applying pending directive at start of turn`);
162
+ // Track directive chain depth (Requirement 22.1)
163
+ const tracker = this.chainTracker;
164
+ tracker.record(directive, "pending");
165
+ // If abort (chain breaker), the tracker stops counting; apply normally below
166
+ // Clear pendingDirective before application (unless complete.next chains another)
167
+ let nextDirective = undefined;
168
+ if (directive.complete &&
169
+ typeof directive.complete === 'object' &&
170
+ directive.complete.next) {
171
+ nextDirective = directive.complete.next;
172
+ }
173
+ targetSession = {
174
+ ...targetSession,
175
+ pendingDirective: nextDirective,
176
+ };
177
+ // Apply the directive: resolve position field to a flow/step
178
+ if (directive.goTo) {
179
+ const flowTarget = typeof directive.goTo === 'string'
180
+ ? directive.goTo
181
+ : directive.goTo.flow;
182
+ if (flowTarget) {
183
+ const targetFlow = flows.find((r) => r.id === flowTarget || r.title === flowTarget);
184
+ if (targetFlow) {
185
+ logger.debug(`[ResponseHandler] Pending directive goTo → flow: ${targetFlow.title}`);
186
+ targetSession = enterFlow(targetSession, targetFlow.id, targetFlow.title);
187
+ // Merge initial data if available
188
+ if (targetFlow.initialData) {
189
+ targetSession = mergeCollected(targetSession, targetFlow.initialData);
190
+ }
191
+ // Merge directive-carried data if present
192
+ if (typeof directive.goTo === 'object' && directive.goTo.data) {
193
+ targetSession = mergeCollected(targetSession, directive.goTo.data);
194
+ }
195
+ selectedFlow = targetFlow;
196
+ // If goTo specifies a step, enter it
197
+ if (typeof directive.goTo === 'object' && directive.goTo.step) {
198
+ const stepTarget = directive.goTo.step;
199
+ const targetStep = targetFlow.getStep(stepTarget);
200
+ if (targetStep) {
201
+ targetSession = enterStep(targetSession, targetStep.id, targetStep.description);
202
+ selectedStep = targetStep;
203
+ }
204
+ }
205
+ }
206
+ else {
207
+ logger.warn(`[FlowConfigurationError] Pending directive goTo target not found: flow "${flowTarget}" does not exist. Falling back to normal routing. Fix the goTo reference or remove the pending directive.`);
208
+ }
74
209
  }
75
- selectedRoute = targetRoute;
76
210
  }
77
- else {
78
- logger.warn(`[ResponseHandler] Pending transition target route not found: ${targetSession.pendingTransition.targetRouteId}`);
79
- // Clear invalid transition
80
- targetSession = {
81
- ...targetSession,
82
- pendingTransition: undefined,
83
- };
211
+ else if (directive.goToStep) {
212
+ const stepTarget = typeof directive.goToStep === 'string'
213
+ ? directive.goToStep
214
+ : directive.goToStep.step;
215
+ const flowTarget = typeof directive.goToStep === 'object'
216
+ ? directive.goToStep.flow
217
+ : undefined;
218
+ if (flowTarget) {
219
+ const targetFlow = flows.find((r) => r.id === flowTarget || r.title === flowTarget);
220
+ if (targetFlow) {
221
+ targetSession = enterFlow(targetSession, targetFlow.id, targetFlow.title);
222
+ selectedFlow = targetFlow;
223
+ const targetStep = targetFlow.getStep(stepTarget);
224
+ if (targetStep) {
225
+ targetSession = enterStep(targetSession, targetStep.id, targetStep.description);
226
+ selectedStep = targetStep;
227
+ }
228
+ }
229
+ }
230
+ else if (targetSession.currentFlow) {
231
+ // Step within current flow
232
+ const currentFlow = flows.find(r => r.id === targetSession.currentFlow?.id);
233
+ if (currentFlow) {
234
+ selectedFlow = currentFlow;
235
+ const targetStep = currentFlow.getStep(stepTarget);
236
+ if (targetStep) {
237
+ targetSession = enterStep(targetSession, targetStep.id, targetStep.description);
238
+ selectedStep = targetStep;
239
+ }
240
+ }
241
+ }
84
242
  }
243
+ else if (directive.reset) {
244
+ // Reset current flow
245
+ if (targetSession.currentFlow) {
246
+ const currentFlow = flows.find(r => r.id === targetSession.currentFlow?.id);
247
+ if (currentFlow) {
248
+ const resetStep = typeof directive.reset === 'object' && directive.reset.step
249
+ ? directive.reset.step
250
+ : undefined;
251
+ selectedFlow = currentFlow;
252
+ if (resetStep) {
253
+ const targetStep = currentFlow.getStep(resetStep);
254
+ if (targetStep) {
255
+ targetSession = enterStep(targetSession, targetStep.id, targetStep.description);
256
+ selectedStep = targetStep;
257
+ }
258
+ }
259
+ else {
260
+ // Reset to initial step
261
+ const initialStep = currentFlow.initialStep;
262
+ targetSession = enterStep(targetSession, initialStep.id, initialStep.description);
263
+ selectedStep = initialStep;
264
+ }
265
+ }
266
+ }
267
+ }
268
+ // For complete/abort, selectedFlow stays undefined → handled downstream
269
+ // Apply state writes from the directive
270
+ if (directive.dataUpdate) {
271
+ targetSession = mergeCollected(targetSession, directive.dataUpdate);
272
+ }
273
+ // Skip FlowRouter.decideFlowAndStep — the directive resolved the position
85
274
  }
86
275
  // If no pending transition or transition handled, do normal routing
87
- if (routes.length > 0 && !selectedRoute) {
88
- const orchestration = await this.routingEngine.decideRouteAndStep({
89
- routes: routes,
276
+ if (flows.length > 0 && !selectedFlow) {
277
+ const orchestration = await this.flowRouter.decideFlowAndStep({
278
+ flows: flows,
90
279
  session: targetSession,
91
280
  history,
92
281
  agentOptions: this.options,
@@ -94,32 +283,60 @@ export class ResponsePipeline {
94
283
  context,
95
284
  signal,
96
285
  });
97
- selectedRoute = orchestration.selectedRoute;
286
+ selectedFlow = orchestration.selectedFlow;
98
287
  selectedStep = orchestration.selectedStep;
99
288
  responseDirectives = orchestration.responseDirectives;
100
289
  targetSession = orchestration.session;
101
- isRouteComplete = orchestration.isRouteComplete || false;
102
- completedRoutes = orchestration.completedRoutes || [];
103
- // Log if route is complete
104
- if (isRouteComplete) {
105
- logger.debug(`[ResponseHandler] Route complete: all required data collected, END_ROUTE reached`);
290
+ isFlowComplete = orchestration.isFlowComplete || false;
291
+ completedFlows = orchestration.completedFlows || [];
292
+ // Log if flow is complete
293
+ if (isFlowComplete) {
294
+ logger.debug(`[ResponseHandler] Flow complete: all required data collected or last step reached`);
106
295
  }
107
296
  }
108
297
  return {
109
- selectedRoute,
298
+ selectedFlow,
110
299
  selectedStep,
111
300
  responseDirectives,
112
301
  session: targetSession,
113
- isRouteComplete,
114
- completedRoutes,
302
+ isFlowComplete,
303
+ completedFlows,
115
304
  };
116
305
  }
117
306
  /**
118
307
  * Determine next step and update session
119
308
  */
120
309
  async determineNextStep(params) {
121
- const { selectedRoute, selectedStep, session, isRouteComplete } = params;
122
- if (!selectedRoute || isRouteComplete) {
310
+ const { selectedFlow, selectedStep, session, isFlowComplete, busDirective } = params;
311
+ if (!selectedFlow) {
312
+ return { nextStep: undefined, session };
313
+ }
314
+ // ─── GUARD: directive bus winner with a position field preempts branches ───
315
+ // Resolution precedence (design.md): bus > branches > linear > AI.
316
+ // If the bus produced a directive with a position field (goTo, goToStep,
317
+ // complete, abort, reset), that decision wins the turn. Do NOT evaluate
318
+ // branches or linear/AI selection — the caller applies the bus directive.
319
+ if (hasDirectivePositionField(busDirective)) {
320
+ logger.debug(`[ResponseHandler] Directive bus winner has position field — skipping branch evaluation and linear/AI selection`);
321
+ return { nextStep: undefined, session };
322
+ }
323
+ // STEP 1 (Algorithm 1): branches win over linear chain AND flow completion.
324
+ // Evaluate branches before checking isFlowComplete — a branch can redirect
325
+ // even from the "last" step (which getCandidateStepsWithConditions marks as complete).
326
+ if (!selectedStep) {
327
+ const currentStep = session.currentFlow?.id === selectedFlow.id && session.currentStep
328
+ ? selectedFlow.getStep(session.currentStep.id)
329
+ : undefined;
330
+ if (currentStep?.branches && currentStep.branches.length > 0) {
331
+ const contextToUse = this.getStoredContext();
332
+ const branchResult = await this.evaluateStepBranches(currentStep, selectedFlow, session, contextToUse);
333
+ if (branchResult) {
334
+ return branchResult;
335
+ }
336
+ // undefined → fall through to linear/AI selection or flow completion
337
+ }
338
+ }
339
+ if (isFlowComplete) {
123
340
  return { nextStep: undefined, session };
124
341
  }
125
342
  let nextStep;
@@ -128,22 +345,22 @@ export class ResponsePipeline {
128
345
  nextStep = selectedStep;
129
346
  }
130
347
  else {
131
- // Determine current step from session if we're already in this route
132
- const currentStep = session.currentRoute?.id === selectedRoute.id && session.currentStep
133
- ? selectedRoute.getStep(session.currentStep.id)
348
+ // Determine current step from session if we're already in this flow
349
+ const currentStep = session.currentFlow?.id === selectedFlow.id && session.currentStep
350
+ ? selectedFlow.getStep(session.currentStep.id)
134
351
  : undefined;
135
352
  const contextToUse = this.getStoredContext();
136
- // Get candidate steps based on current position in the route
137
- const candidates = await this.routingEngine.getCandidateStepsWithConditions(selectedRoute, currentStep, // Pass current step instead of undefined to maintain progression
353
+ // Get candidate steps based on current position in the flow
354
+ const candidates = await this.flowRouter.getCandidateStepsWithConditions(selectedFlow, currentStep, // Pass current step instead of undefined to maintain progression
138
355
  createTemplateContext({ data: session.data, session, context: contextToUse }));
139
356
  if (candidates.length > 0) {
140
357
  nextStep = candidates[0].step;
141
- logger.debug(`[ResponseHandler] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new route'}`);
358
+ logger.debug(`[ResponseHandler] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new flow'}`);
142
359
  }
143
360
  else {
144
361
  // Fallback to initial step even if it should be skipped
145
- nextStep = selectedRoute.initialStep;
146
- logger.warn(`[ResponseHandler] No valid steps found, using initial step: ${nextStep.id}`);
362
+ nextStep = selectedFlow.initialStep;
363
+ logger.warn(`[FlowConfigurationError] No valid steps found in flow "${selectedFlow.title}": all candidates were skipped. Falling back to initial step "${nextStep.id}". Review step skip conditions.`);
147
364
  }
148
365
  }
149
366
  // Before entering the step, check if requires fields are satisfied
@@ -154,8 +371,8 @@ export class ResponsePipeline {
154
371
  logger.debug(`[ResponseHandler] Cannot enter step "${nextStep.id}": missing required fields [${missingRequires.join(', ')}]. Staying at current step.`);
155
372
  // Stay at current step - don't enter the next one
156
373
  const currentStepId = session.currentStep?.id;
157
- if (currentStepId && selectedRoute) {
158
- const currentStepInstance = selectedRoute.getStep(currentStepId);
374
+ if (currentStepId && selectedFlow) {
375
+ const currentStepInstance = selectedFlow.getStep(currentStepId);
159
376
  if (currentStepInstance) {
160
377
  nextStep = currentStepInstance;
161
378
  }
@@ -168,11 +385,158 @@ export class ResponsePipeline {
168
385
  logger.debug(`[ResponseHandler] Entered step: ${nextStep.id}`);
169
386
  return { nextStep, session: updatedSession };
170
387
  }
388
+ /**
389
+ * Evaluate branches on a step and resolve the `then` value.
390
+ *
391
+ * Resolution rules (Algorithm 1, STEP 1 + then resolution):
392
+ * - String `then` → look up in current flow's step registry first (local step wins).
393
+ * - Not a local step → look up in agent's flow registry; if found, treat as goTo directive.
394
+ * - Neither → throw FlowConfigurationError.
395
+ * - Directive `then` → apply directly (bypass directive bus merge).
396
+ *
397
+ * Returns the resolved { nextStep, session, flowChanged? } or undefined if no branch matched.
398
+ */
399
+ async evaluateStepBranches(currentStep, selectedFlow, session, context) {
400
+ const history = session.history ? historyToEvents(session.history) : [];
401
+ // Build the BranchPredicateContext
402
+ const branchCtx = {
403
+ data: session.data,
404
+ context,
405
+ session,
406
+ history,
407
+ };
408
+ // Create the AI condition evaluator
409
+ const aiEvaluator = createAiConditionEvaluator(this.options.provider, history, context);
410
+ const result = await evaluateBranches(currentStep.branches, branchCtx, aiEvaluator);
411
+ if (result === undefined) {
412
+ return undefined; // No branch matched → fall through to linear/AI selection
413
+ }
414
+ // Task 4.3: Directive `then` value — apply directly
415
+ if (typeof result === 'object' && result !== null) {
416
+ const directive = result;
417
+ return this.applyBranchDirective(directive, selectedFlow, session);
418
+ }
419
+ // Task 4.2: String `then` resolution
420
+ // 1. Look up in current flow's step registry first (local step wins)
421
+ const localStep = selectedFlow.getStep(result);
422
+ if (localStep) {
423
+ const updatedSession = enterStep(session, localStep.id, localStep.description);
424
+ logger.debug(`[ResponseHandler] Branch resolved to local step: ${localStep.id}`);
425
+ return { nextStep: localStep, session: updatedSession };
426
+ }
427
+ // 2. Look up in agent's flow registry
428
+ const flows = this.getFlows();
429
+ const targetFlow = flows.find(f => f.id === result || f.title === result);
430
+ if (targetFlow) {
431
+ // Treat as applyDirective({ goTo: result }) — enter the target flow
432
+ logger.debug(`[ResponseHandler] Branch resolved to flow: ${targetFlow.title}`);
433
+ const updatedSession = enterFlow(session, targetFlow.id, targetFlow.title);
434
+ return { nextStep: undefined, session: updatedSession, flowChanged: targetFlow };
435
+ }
436
+ // 3. Neither → throw FlowConfigurationError
437
+ throw new FlowConfigurationError(`[FlowConfigurationError] Unresolved branch target: "${result}" does not match any step in flow "${selectedFlow.id}" or any flow in the agent. ` +
438
+ `Source: ${selectedFlow.id}.${currentStep.id}. Fix the branch "then" value to reference a valid step id or flow id/title.`);
439
+ }
440
+ /**
441
+ * Apply a Directive returned by a branch entry's `then` value.
442
+ * Branches bypass the directive bus — the Directive is the position decision.
443
+ */
444
+ applyBranchDirective(directive, selectedFlow, session) {
445
+ // Track directive chain depth (Requirement 22.1)
446
+ const tracker = this.chainTracker;
447
+ tracker.record(directive, `branch:${selectedFlow.id}`);
448
+ let updatedSession = session;
449
+ // Apply state writes first
450
+ if (directive.dataUpdate) {
451
+ updatedSession = mergeCollected(updatedSession, directive.dataUpdate);
452
+ }
453
+ // Handle position fields
454
+ if (directive.goToStep) {
455
+ const stepTarget = typeof directive.goToStep === 'string'
456
+ ? directive.goToStep
457
+ : directive.goToStep.step;
458
+ const flowTarget = typeof directive.goToStep === 'object'
459
+ ? directive.goToStep.flow
460
+ : undefined;
461
+ if (flowTarget) {
462
+ // Cross-flow step reference — enter the target flow first
463
+ const flows = this.getFlows();
464
+ const targetFlow = flows.find(f => f.id === flowTarget || f.title === flowTarget);
465
+ if (targetFlow) {
466
+ updatedSession = enterFlow(updatedSession, targetFlow.id, targetFlow.title);
467
+ updatedSession = enterStep(updatedSession, stepTarget);
468
+ // Try to resolve the target step instance for the caller
469
+ const targetStepInstance = targetFlow.getStep(stepTarget);
470
+ logger.debug(`[ResponseHandler] Branch directive goToStep → ${flowTarget}.${stepTarget}`);
471
+ return { nextStep: targetStepInstance || undefined, session: updatedSession, flowChanged: targetFlow };
472
+ }
473
+ throw new FlowConfigurationError(`[FlowConfigurationError] Branch directive goToStep targets unknown flow: "${flowTarget}" does not match any flow id or title. ` +
474
+ `Fix the goToStep.flow value or use goTo to target a known flow.`);
475
+ }
476
+ // Local step reference
477
+ const targetStep = selectedFlow.getStep(stepTarget);
478
+ if (targetStep) {
479
+ updatedSession = enterStep(updatedSession, targetStep.id, targetStep.description);
480
+ logger.debug(`[ResponseHandler] Branch directive goToStep → ${targetStep.id}`);
481
+ return { nextStep: targetStep, session: updatedSession };
482
+ }
483
+ throw new FlowConfigurationError(`[FlowConfigurationError] Branch directive goToStep targets unknown step: "${stepTarget}" does not exist in flow "${selectedFlow.id}". ` +
484
+ `Fix the goToStep value to reference a valid step id in the current flow.`);
485
+ }
486
+ if (directive.goTo) {
487
+ const flowTarget = typeof directive.goTo === 'string'
488
+ ? directive.goTo
489
+ : directive.goTo.flow ?? directive.goTo.step;
490
+ if (flowTarget) {
491
+ const flows = this.getFlows();
492
+ const targetFlow = flows.find(f => f.id === flowTarget || f.title === flowTarget);
493
+ if (targetFlow) {
494
+ updatedSession = enterFlow(updatedSession, targetFlow.id, targetFlow.title);
495
+ // If goTo is an object with a step field, enter that step too
496
+ if (typeof directive.goTo === 'object' && directive.goTo.step) {
497
+ updatedSession = enterStep(updatedSession, directive.goTo.step);
498
+ }
499
+ logger.debug(`[ResponseHandler] Branch directive goTo → ${targetFlow.title}`);
500
+ return { nextStep: undefined, session: updatedSession, flowChanged: targetFlow };
501
+ }
502
+ throw new FlowConfigurationError(`[FlowConfigurationError] Branch directive goTo targets unknown flow: "${flowTarget}" does not match any flow id or title. ` +
503
+ `Fix the goTo value to reference a valid flow.`);
504
+ }
505
+ }
506
+ if (directive.complete) {
507
+ logger.debug(`[ResponseHandler] Branch directive complete`);
508
+ return { nextStep: undefined, session: updatedSession };
509
+ }
510
+ if (directive.abort) {
511
+ logger.debug(`[ResponseHandler] Branch directive abort`);
512
+ return { nextStep: undefined, session: updatedSession };
513
+ }
514
+ if (directive.reset) {
515
+ const resetStep = typeof directive.reset === 'object' && directive.reset.step
516
+ ? directive.reset.step
517
+ : undefined;
518
+ if (resetStep) {
519
+ const targetStep = selectedFlow.getStep(resetStep);
520
+ if (targetStep) {
521
+ updatedSession = enterStep(updatedSession, targetStep.id, targetStep.description);
522
+ return { nextStep: targetStep, session: updatedSession };
523
+ }
524
+ }
525
+ // Reset to initial step
526
+ const initialStep = selectedFlow.initialStep;
527
+ updatedSession = enterStep(updatedSession, initialStep.id, initialStep.description);
528
+ logger.debug(`[ResponseHandler] Branch directive reset → ${initialStep.id}`);
529
+ return { nextStep: initialStep, session: updatedSession };
530
+ }
531
+ // Directive with only non-position fields (e.g., just dataUpdate/contextUpdate/reply)
532
+ // No position change — fall through to linear selection
533
+ return { nextStep: undefined, session: updatedSession };
534
+ }
171
535
  /**
172
536
  * Execute tool calls and handle results
173
537
  */
174
538
  async executeToolCalls(params) {
175
- const { toolCalls, selectedRoute, context, session, history, isStreaming = false, } = params;
539
+ const { toolCalls, selectedFlow, context, session, history, isStreaming = false, } = params;
176
540
  if (toolCalls.length === 0) {
177
541
  return { session, toolCalls: undefined };
178
542
  }
@@ -181,9 +545,9 @@ export class ResponsePipeline {
181
545
  const executedToolCalls = [];
182
546
  const toolResults = new Map();
183
547
  for (const toolCall of toolCalls) {
184
- const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
548
+ const tool = this.findAvailableTool(toolCall.toolName, selectedFlow);
185
549
  if (!tool) {
186
- logger.warn(`[ResponseHandler] Tool not found: ${toolCall.toolName}`);
550
+ logger.warn(`[ToolExecutionError] Tool not found: "${toolCall.toolName}" is not registered in any scope (transient, step, flow, or agent). Skipping this tool call. Register the tool or check the tool name.`);
187
551
  continue;
188
552
  }
189
553
  // Use ToolManager for unified tool execution
@@ -214,7 +578,7 @@ export class ResponsePipeline {
214
578
  updatedSession = await this.updateData(updatedSession, result.dataUpdate);
215
579
  logger.debug(`[ResponseHandler] ${isStreaming ? "Streaming " : ""}Tool updated collected data:`, result.dataUpdate);
216
580
  }
217
- logger.debug(`[ResponseHandler] Executed ${isStreaming ? "streaming " : ""}tool: ${String(tool.id || tool.name || 'unknown')} (success: ${result.success})`);
581
+ logger.debug(`[ResponseHandler] Executed ${isStreaming ? "streaming " : ""}tool: ${String(tool.id || tool.id || 'unknown')} (success: ${result.success})`);
218
582
  }
219
583
  return {
220
584
  session: updatedSession,
@@ -226,7 +590,7 @@ export class ResponsePipeline {
226
590
  * Execute tool loop for follow-up tool calls
227
591
  */
228
592
  async executeToolLoop(params) {
229
- const { initialToolCalls, selectedRoute, nextStep, responsePrompt, history, context, session, responseSchema, isStreaming = false, } = params;
593
+ const { initialToolCalls, selectedFlow, nextStep, responsePrompt, history, context, session, responseSchema, isStreaming = false, } = params;
230
594
  const MAX_TOOL_LOOPS = 5;
231
595
  let toolLoopCount = 0;
232
596
  let currentToolCalls = initialToolCalls;
@@ -240,7 +604,7 @@ export class ResponsePipeline {
240
604
  // Add tool execution results to history so AI knows what happened
241
605
  const toolResultItems = [];
242
606
  for (const toolCall of currentToolCalls || []) {
243
- const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
607
+ const tool = this.findAvailableTool(toolCall.toolName, selectedFlow);
244
608
  if (tool) {
245
609
  toolResultItems.push({
246
610
  role: "assistant",
@@ -266,7 +630,7 @@ export class ResponsePipeline {
266
630
  prompt: responsePrompt,
267
631
  history: updatedHistory,
268
632
  context,
269
- tools: this.collectAvailableTools(selectedRoute, nextStep),
633
+ tools: this.collectAvailableTools(selectedFlow, nextStep),
270
634
  parameters: {
271
635
  jsonSchema: responseSchema,
272
636
  schemaName: isStreaming ? "tool_followup_streaming" : "tool_followup",
@@ -280,7 +644,7 @@ export class ResponsePipeline {
280
644
  // Execute the follow-up tool calls
281
645
  const toolResult = await this.executeToolCalls({
282
646
  toolCalls: followUpToolCalls,
283
- selectedRoute,
647
+ selectedFlow,
284
648
  context,
285
649
  session: currentSession,
286
650
  history: historyToEvents(updatedHistory),
@@ -298,7 +662,7 @@ export class ResponsePipeline {
298
662
  }
299
663
  }
300
664
  if (toolLoopCount >= MAX_TOOL_LOOPS) {
301
- logger.warn(`[ResponseHandler] ${isStreaming ? "Streaming " : ""}Tool loop limit reached (${MAX_TOOL_LOOPS}), stopping`);
665
+ logger.warn(`[ResponseGenerationError] ${isStreaming ? "Streaming t" : "T"}ool loop limit reached: ${toolLoopCount} iterations hit the cap (${MAX_TOOL_LOOPS}). Stopping tool execution. Increase MAX_TOOL_LOOPS or reduce recursive tool calls.`);
302
666
  }
303
667
  return {
304
668
  session: currentSession,
@@ -349,77 +713,85 @@ export class ResponsePipeline {
349
713
  }
350
714
  }
351
715
  /**
352
- * Handle route completion logic
716
+ * Handle flow completion: pure state transition.
717
+ *
718
+ * Releases the session to idle (`currentFlow`/`currentStep` cleared),
719
+ * marks the active `flowHistory` entry completed, and (when `onComplete`
720
+ * is set) wires `pendingDirective` for the next turn. The framework
721
+ * emits no message of its own at the completion boundary; callers that
722
+ * need closing copy should add a final interactive step.
353
723
  */
354
- async handleRouteCompletion(params) {
355
- const { selectedRoute, session, context, history } = params;
724
+ async handleFlowCompletion(params) {
725
+ const { selectedFlow, session, context } = params;
356
726
  // Check for onComplete transition
357
- const transitionConfig = await selectedRoute.evaluateOnComplete({ data: session.data }, context);
727
+ const transitionConfig = await selectedFlow.evaluateOnComplete({ data: session.data }, context);
728
+ // Release to idle. When the flow is reentrant, scrub its owned
729
+ // fields so a future re-selection doesn't short-circuit on stale data.
730
+ const ownedFields = selectedFlow.reentrant
731
+ ? [
732
+ ...(selectedFlow.requiredFields ?? []),
733
+ ...(selectedFlow.optionalFields ?? []),
734
+ ]
735
+ : undefined;
736
+ let updatedSession = completeCurrentFlow(session, {
737
+ clearOwnedFields: ownedFields,
738
+ });
358
739
  if (transitionConfig) {
359
- // Find target route by ID or title
360
- const targetRoute = this.getRoutes().find((r) => r.id === transitionConfig.nextStep ||
361
- r.title === transitionConfig.nextStep);
362
- if (targetRoute) {
363
- const templateContext = createTemplateContext({
364
- context,
365
- session,
366
- history,
367
- });
368
- const renderedCondition = (await render(transitionConfig.condition, templateContext)) ||
369
- (typeof transitionConfig.condition === "string"
370
- ? transitionConfig.condition
371
- : "");
372
- // Set pending transition in session
373
- const updatedSession = {
374
- ...session,
375
- pendingTransition: {
376
- targetRouteId: targetRoute.id,
377
- condition: renderedCondition,
378
- reason: "route_complete",
740
+ // Extract target from directive's goTo field
741
+ const goToTarget = typeof transitionConfig.goTo === 'string'
742
+ ? transitionConfig.goTo
743
+ : transitionConfig.goTo?.flow;
744
+ // Find target flow by ID or title
745
+ const targetFlow = goToTarget ? this.getFlows().find((r) => r.id === goToTarget ||
746
+ r.title === goToTarget) : undefined;
747
+ if (targetFlow) {
748
+ updatedSession = {
749
+ ...updatedSession,
750
+ pendingDirective: {
751
+ goTo: targetFlow.id,
379
752
  },
380
753
  };
381
- logger.debug(`[ResponseHandler] Route ${selectedRoute.title} completed with pending transition to: ${targetRoute.title}`);
754
+ logger.debug(`[ResponseHandler] Flow ${selectedFlow.title} completed with pending directive to: ${targetFlow.title}`);
382
755
  return { session: updatedSession, hasTransition: true };
383
756
  }
384
- else {
385
- logger.warn(`[ResponseHandler] Route ${selectedRoute.title} completed but target route not found: ${transitionConfig.nextStep}`);
757
+ else if (goToTarget) {
758
+ logger.warn(`[FlowConfigurationError] onComplete target not found: flow "${selectedFlow.title}" completed but onComplete target "${goToTarget}" does not match any flow. ` +
759
+ `Fix the onComplete value to reference an existing flow id/title, or remove onComplete to release the session to idle.`);
386
760
  }
387
761
  }
388
- // Set step to END_ROUTE marker
389
- const updatedSession = enterStep(session, END_ROUTE_ID, "Route completed");
390
- logger.debug(`[ResponseHandler] Route ${selectedRoute.title} completed. Entered END_ROUTE step.`);
762
+ logger.debug(`[ResponseHandler] Flow ${selectedFlow.title} completed; session released to idle.`);
391
763
  return { session: updatedSession, hasTransition: false };
392
764
  }
393
765
  /**
394
- * Find an available tool by name for the given route using ToolManager
766
+ * Find an available tool by name for the given flow using ToolManager
395
767
  * Delegates to ToolManager for unified tool resolution
396
768
  */
397
- findAvailableTool(toolName, route) {
769
+ findAvailableTool(toolName, flow) {
398
770
  // Use ToolManager for unified tool resolution if available
399
771
  if (this.toolManager) {
400
- return this.toolManager.find(toolName, undefined, undefined, route);
772
+ return this.toolManager.find(toolName, undefined, undefined, flow);
401
773
  }
402
774
  // Fallback to legacy resolution if ToolManager not available
403
775
  logger.warn(`[ResponsePipeline] ToolManager not available, using legacy tool resolution for: ${toolName}`);
404
- // Check route-level tools first (if route provided)
405
- if (route) {
406
- const routeTool = route
776
+ // Check flow-level tools first (if flow provided)
777
+ if (flow) {
778
+ const flowTool = flow
407
779
  .getTools()
408
- .find((tool) => tool.id === toolName || tool.name === toolName);
409
- if (routeTool)
410
- return routeTool;
780
+ .find((tool) => tool.id === toolName || tool.id === toolName);
781
+ if (flowTool)
782
+ return flowTool;
411
783
  }
412
784
  // Fall back to agent-level tools
413
- return this.tools.find((tool) => tool.id === toolName || tool.name === toolName);
785
+ return this.tools.find((tool) => tool.id === toolName || tool.id === toolName);
414
786
  }
415
787
  /**
416
- * Collect all available tools for the given route and step context using ToolManager
788
+ * Collect all available tools for the given flow and step context using ToolManager
417
789
  * Delegates to ToolManager for unified tool resolution and deduplication
418
790
  */
419
- collectAvailableTools(route, step) {
791
+ collectAvailableTools(flow, step) {
420
792
  // Use ToolManager for unified tool collection if available
421
793
  if (this.toolManager) {
422
- const availableTools = this.toolManager.getAvailable(undefined, step, route);
794
+ const availableTools = this.toolManager.getAvailable(undefined, step, flow);
423
795
  return availableTools.map((tool) => ({
424
796
  id: tool.id,
425
797
  description: tool.description,
@@ -433,9 +805,9 @@ export class ResponsePipeline {
433
805
  this.tools.forEach((tool) => {
434
806
  availableTools.set(tool.id, tool);
435
807
  });
436
- // Add route-level tools (these take precedence)
437
- if (route) {
438
- route.getTools().forEach((tool) => {
808
+ // Add flow-level tools (these take precedence)
809
+ if (flow) {
810
+ flow.getTools().forEach((tool) => {
439
811
  availableTools.set(tool.id, tool);
440
812
  });
441
813
  }
@@ -507,34 +879,34 @@ export class ResponsePipeline {
507
879
  return this.currentSession;
508
880
  }
509
881
  /**
510
- * Handle cross-route completion evaluation and notifications
511
- * This method evaluates all routes for completion and can trigger completion handlers
882
+ * Handle cross-flow completion evaluation and notifications
883
+ * This method evaluates all flows for completion and can trigger completion handlers
512
884
  */
513
- async handleCrossRouteCompletion(params) {
514
- const { routes, session, context } = params;
515
- // Evaluate all routes for completion
516
- const completedRoutes = [];
885
+ async handleCrossFlowCompletion(params) {
886
+ const { flows, session, context } = params;
887
+ // Evaluate all flows for completion
888
+ const completedFlows = [];
517
889
  const pendingTransitions = [];
518
- for (const route of routes) {
519
- if (route.isComplete(session.data || {})) {
520
- completedRoutes.push(route);
890
+ for (const flow of flows) {
891
+ if (flow.isComplete(session.data || {})) {
892
+ completedFlows.push(flow);
521
893
  // Check for onComplete transitions
522
- const transitionConfig = await route.evaluateOnComplete({ data: session.data }, context);
894
+ const transitionConfig = await flow.evaluateOnComplete({ data: session.data }, context);
523
895
  if (transitionConfig) {
524
- pendingTransitions.push({ route, transitionConfig });
896
+ pendingTransitions.push({ flow, transitionConfig });
525
897
  }
526
- logger.debug(`[ResponsePipeline] Route completed: ${route.title} ` +
527
- `(${Math.round(route.getCompletionProgress(session.data || {}) * 100)}%)`);
898
+ logger.debug(`[ResponsePipeline] Flow completed: ${flow.title} ` +
899
+ `(${Math.round(flow.getCompletionProgress(session.data || {}) * 100)}%)`);
528
900
  }
529
901
  }
530
- // Log completion status for all routes
531
- if (completedRoutes.length > 0) {
532
- logger.debug(`[ResponsePipeline] Cross-route completion evaluation: ` +
533
- `${completedRoutes.length}/${routes.length} routes complete`);
902
+ // Log completion status for all flows
903
+ if (completedFlows.length > 0) {
904
+ logger.debug(`[ResponsePipeline] Cross-flow completion evaluation: ` +
905
+ `${completedFlows.length}/${flows.length} flows complete`);
534
906
  }
535
907
  return {
536
908
  session,
537
- completedRoutes,
909
+ completedFlows,
538
910
  pendingTransitions,
539
911
  };
540
912
  }
@@ -543,23 +915,23 @@ export class ResponsePipeline {
543
915
  * This method ensures that data updates are properly validated and propagated
544
916
  */
545
917
  async updateDataFlow(params) {
546
- const { session, dataUpdate, routes } = params;
918
+ const { session, dataUpdate, flows } = params;
547
919
  // Update session data
548
920
  const updatedSession = await this.updateData(session, dataUpdate);
549
921
  // Update agent-level data if handler is available
550
922
  if (this.updateCollectedData) {
551
923
  await this.updateCollectedData(dataUpdate);
552
924
  }
553
- // Evaluate route completions after data update
554
- const completionResults = await this.handleCrossRouteCompletion({
555
- routes,
925
+ // Evaluate flow completions after data update
926
+ const completionResults = await this.handleCrossFlowCompletion({
927
+ flows,
556
928
  session: updatedSession,
557
929
  context: this.context,
558
930
  history: [],
559
931
  });
560
- // Log any newly completed routes
561
- if (completionResults.completedRoutes.length > 0) {
562
- logger.debug(`[ResponsePipeline] Data update resulted in ${completionResults.completedRoutes.length} completed routes`);
932
+ // Log any newly completed flows
933
+ if (completionResults.completedFlows.length > 0) {
934
+ logger.debug(`[ResponsePipeline] Data update resulted in ${completionResults.completedFlows.length} completed flows`);
563
935
  }
564
936
  return completionResults.session;
565
937
  }