@falai/agent 2.6.1 → 3.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 (611) hide show
  1. package/README.md +2 -2
  2. package/dist/adapters/MemoryAdapter.d.ts +1 -1
  3. package/dist/adapters/MemoryAdapter.d.ts.map +1 -1
  4. package/dist/adapters/MemoryAdapter.js +32 -36
  5. package/dist/adapters/MemoryAdapter.js.map +1 -1
  6. package/dist/adapters/MongoAdapter.d.ts +1 -1
  7. package/dist/adapters/MongoAdapter.d.ts.map +1 -1
  8. package/dist/adapters/MongoAdapter.js +2 -2
  9. package/dist/adapters/MongoAdapter.js.map +1 -1
  10. package/dist/adapters/OpenSearchAdapter.d.ts +1 -1
  11. package/dist/adapters/OpenSearchAdapter.d.ts.map +1 -1
  12. package/dist/adapters/OpenSearchAdapter.js +3 -3
  13. package/dist/adapters/OpenSearchAdapter.js.map +1 -1
  14. package/dist/adapters/PostgreSQLAdapter.d.ts +1 -1
  15. package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  16. package/dist/adapters/PostgreSQLAdapter.js +18 -13
  17. package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
  18. package/dist/adapters/PrismaAdapter.d.ts +1 -1
  19. package/dist/adapters/PrismaAdapter.d.ts.map +1 -1
  20. package/dist/adapters/PrismaAdapter.js +3 -3
  21. package/dist/adapters/PrismaAdapter.js.map +1 -1
  22. package/dist/adapters/RedisAdapter.d.ts +2 -1
  23. package/dist/adapters/RedisAdapter.d.ts.map +1 -1
  24. package/dist/adapters/RedisAdapter.js +77 -27
  25. package/dist/adapters/RedisAdapter.js.map +1 -1
  26. package/dist/adapters/SQLiteAdapter.d.ts +1 -1
  27. package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
  28. package/dist/adapters/SQLiteAdapter.js +9 -31
  29. package/dist/adapters/SQLiteAdapter.js.map +1 -1
  30. package/dist/adapters/index.d.ts +13 -13
  31. package/dist/adapters/index.d.ts.map +1 -1
  32. package/dist/adapters/index.js +7 -7
  33. package/dist/adapters/index.js.map +1 -1
  34. package/dist/adapters/sessionRow.d.ts +22 -0
  35. package/dist/adapters/sessionRow.d.ts.map +1 -0
  36. package/dist/adapters/sessionRow.js +48 -0
  37. package/dist/adapters/sessionRow.js.map +1 -0
  38. package/dist/cjs/adapters/MemoryAdapter.d.ts +1 -1
  39. package/dist/cjs/adapters/MemoryAdapter.d.ts.map +1 -1
  40. package/dist/cjs/adapters/MemoryAdapter.js +39 -43
  41. package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
  42. package/dist/cjs/adapters/MongoAdapter.d.ts +1 -1
  43. package/dist/cjs/adapters/MongoAdapter.d.ts.map +1 -1
  44. package/dist/cjs/adapters/MongoAdapter.js +4 -4
  45. package/dist/cjs/adapters/MongoAdapter.js.map +1 -1
  46. package/dist/cjs/adapters/OpenSearchAdapter.d.ts +1 -1
  47. package/dist/cjs/adapters/OpenSearchAdapter.d.ts.map +1 -1
  48. package/dist/cjs/adapters/OpenSearchAdapter.js +6 -6
  49. package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -1
  50. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts +1 -1
  51. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  52. package/dist/cjs/adapters/PostgreSQLAdapter.js +20 -15
  53. package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
  54. package/dist/cjs/adapters/PrismaAdapter.d.ts +1 -1
  55. package/dist/cjs/adapters/PrismaAdapter.d.ts.map +1 -1
  56. package/dist/cjs/adapters/PrismaAdapter.js +7 -7
  57. package/dist/cjs/adapters/PrismaAdapter.js.map +1 -1
  58. package/dist/cjs/adapters/RedisAdapter.d.ts +2 -1
  59. package/dist/cjs/adapters/RedisAdapter.d.ts.map +1 -1
  60. package/dist/cjs/adapters/RedisAdapter.js +81 -31
  61. package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
  62. package/dist/cjs/adapters/SQLiteAdapter.d.ts +1 -1
  63. package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
  64. package/dist/cjs/adapters/SQLiteAdapter.js +11 -33
  65. package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -1
  66. package/dist/cjs/adapters/index.d.ts +13 -13
  67. package/dist/cjs/adapters/index.d.ts.map +1 -1
  68. package/dist/cjs/adapters/index.js +14 -14
  69. package/dist/cjs/adapters/index.js.map +1 -1
  70. package/dist/cjs/adapters/sessionRow.d.ts +22 -0
  71. package/dist/cjs/adapters/sessionRow.d.ts.map +1 -0
  72. package/dist/cjs/adapters/sessionRow.js +52 -0
  73. package/dist/cjs/adapters/sessionRow.js.map +1 -0
  74. package/dist/cjs/core/Agent.d.ts +19 -11
  75. package/dist/cjs/core/Agent.d.ts.map +1 -1
  76. package/dist/cjs/core/Agent.js +102 -64
  77. package/dist/cjs/core/Agent.js.map +1 -1
  78. package/dist/cjs/core/AutoChainExecutor.d.ts +12 -22
  79. package/dist/cjs/core/AutoChainExecutor.d.ts.map +1 -1
  80. package/dist/cjs/core/AutoChainExecutor.js +46 -49
  81. package/dist/cjs/core/AutoChainExecutor.js.map +1 -1
  82. package/dist/cjs/core/BranchEvaluator.d.ts +4 -4
  83. package/dist/cjs/core/BranchEvaluator.d.ts.map +1 -1
  84. package/dist/cjs/core/BranchEvaluator.js +6 -6
  85. package/dist/cjs/core/BranchEvaluator.js.map +1 -1
  86. package/dist/cjs/core/CompactionEngine.d.ts +16 -3
  87. package/dist/cjs/core/CompactionEngine.d.ts.map +1 -1
  88. package/dist/cjs/core/CompactionEngine.js +30 -6
  89. package/dist/cjs/core/CompactionEngine.js.map +1 -1
  90. package/dist/cjs/core/DirectiveChainTracker.d.ts +1 -1
  91. package/dist/cjs/core/DirectiveChainTracker.d.ts.map +1 -1
  92. package/dist/cjs/core/DirectiveChainTracker.js +5 -5
  93. package/dist/cjs/core/DirectiveChainTracker.js.map +1 -1
  94. package/dist/cjs/core/Events.d.ts +1 -1
  95. package/dist/cjs/core/Events.d.ts.map +1 -1
  96. package/dist/cjs/core/Events.js +15 -15
  97. package/dist/cjs/core/Events.js.map +1 -1
  98. package/dist/cjs/core/Flow.d.ts +4 -4
  99. package/dist/cjs/core/Flow.d.ts.map +1 -1
  100. package/dist/cjs/core/Flow.js +15 -15
  101. package/dist/cjs/core/Flow.js.map +1 -1
  102. package/dist/cjs/core/FlowRouter.d.ts +4 -4
  103. package/dist/cjs/core/FlowRouter.d.ts.map +1 -1
  104. package/dist/cjs/core/FlowRouter.js +92 -70
  105. package/dist/cjs/core/FlowRouter.js.map +1 -1
  106. package/dist/cjs/core/PersistenceManager.d.ts +1 -1
  107. package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
  108. package/dist/cjs/core/PersistenceManager.js +10 -10
  109. package/dist/cjs/core/PersistenceManager.js.map +1 -1
  110. package/dist/cjs/core/PromptComposer.d.ts +4 -4
  111. package/dist/cjs/core/PromptComposer.d.ts.map +1 -1
  112. package/dist/cjs/core/PromptComposer.js +13 -13
  113. package/dist/cjs/core/PromptComposer.js.map +1 -1
  114. package/dist/cjs/core/PromptSectionCache.d.ts +2 -2
  115. package/dist/cjs/core/PromptSectionCache.d.ts.map +1 -1
  116. package/dist/cjs/core/ResponseEngine.d.ts +4 -4
  117. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
  118. package/dist/cjs/core/ResponseEngine.js +7 -7
  119. package/dist/cjs/core/ResponseEngine.js.map +1 -1
  120. package/dist/cjs/core/ResponseGenerationError.d.ts.map +1 -1
  121. package/dist/cjs/core/ResponseGenerationError.js +3 -5
  122. package/dist/cjs/core/ResponseGenerationError.js.map +1 -1
  123. package/dist/cjs/core/ResponseModal.d.ts +39 -10
  124. package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
  125. package/dist/cjs/core/ResponseModal.js +195 -72
  126. package/dist/cjs/core/ResponseModal.js.map +1 -1
  127. package/dist/cjs/core/ResponsePipeline.d.ts +50 -12
  128. package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -1
  129. package/dist/cjs/core/ResponsePipeline.js +301 -158
  130. package/dist/cjs/core/ResponsePipeline.js.map +1 -1
  131. package/dist/cjs/core/SessionFinalizer.d.ts +4 -4
  132. package/dist/cjs/core/SessionFinalizer.d.ts.map +1 -1
  133. package/dist/cjs/core/SessionFinalizer.js +36 -9
  134. package/dist/cjs/core/SessionFinalizer.js.map +1 -1
  135. package/dist/cjs/core/SessionManager.d.ts +15 -6
  136. package/dist/cjs/core/SessionManager.d.ts.map +1 -1
  137. package/dist/cjs/core/SessionManager.js +49 -22
  138. package/dist/cjs/core/SessionManager.js.map +1 -1
  139. package/dist/cjs/core/SignalCoordinator.d.ts +5 -5
  140. package/dist/cjs/core/SignalCoordinator.d.ts.map +1 -1
  141. package/dist/cjs/core/SignalCoordinator.js +12 -12
  142. package/dist/cjs/core/SignalCoordinator.js.map +1 -1
  143. package/dist/cjs/core/SignalEvaluator.d.ts +4 -4
  144. package/dist/cjs/core/SignalEvaluator.d.ts.map +1 -1
  145. package/dist/cjs/core/SignalEvaluator.js +6 -6
  146. package/dist/cjs/core/SignalEvaluator.js.map +1 -1
  147. package/dist/cjs/core/SignalProcessor.d.ts +6 -6
  148. package/dist/cjs/core/SignalProcessor.d.ts.map +1 -1
  149. package/dist/cjs/core/SignalProcessor.js +17 -89
  150. package/dist/cjs/core/SignalProcessor.js.map +1 -1
  151. package/dist/cjs/core/Step.d.ts +5 -5
  152. package/dist/cjs/core/Step.d.ts.map +1 -1
  153. package/dist/cjs/core/Step.js +65 -17
  154. package/dist/cjs/core/Step.js.map +1 -1
  155. package/dist/cjs/core/StepLifecycle.d.ts +18 -8
  156. package/dist/cjs/core/StepLifecycle.d.ts.map +1 -1
  157. package/dist/cjs/core/StepLifecycle.js +103 -20
  158. package/dist/cjs/core/StepLifecycle.js.map +1 -1
  159. package/dist/cjs/core/StreamingToolExecutor.d.ts +1 -1
  160. package/dist/cjs/core/StreamingToolExecutor.d.ts.map +1 -1
  161. package/dist/cjs/core/StreamingToolExecutor.js +30 -6
  162. package/dist/cjs/core/StreamingToolExecutor.js.map +1 -1
  163. package/dist/cjs/core/ToolLoopExecutor.d.ts +8 -4
  164. package/dist/cjs/core/ToolLoopExecutor.d.ts.map +1 -1
  165. package/dist/cjs/core/ToolLoopExecutor.js +189 -97
  166. package/dist/cjs/core/ToolLoopExecutor.js.map +1 -1
  167. package/dist/cjs/core/ToolManager.d.ts +6 -6
  168. package/dist/cjs/core/ToolManager.d.ts.map +1 -1
  169. package/dist/cjs/core/ToolManager.js +102 -79
  170. package/dist/cjs/core/ToolManager.js.map +1 -1
  171. package/dist/cjs/core/createAgent.d.ts +2 -2
  172. package/dist/cjs/core/createAgent.d.ts.map +1 -1
  173. package/dist/cjs/core/createAgent.js +2 -2
  174. package/dist/cjs/core/createAgent.js.map +1 -1
  175. package/dist/cjs/core/flow-namespace.d.ts +16 -1
  176. package/dist/cjs/core/flow-namespace.d.ts.map +1 -1
  177. package/dist/cjs/core/flow-namespace.js +26 -4
  178. package/dist/cjs/core/flow-namespace.js.map +1 -1
  179. package/dist/cjs/core/toolGates.d.ts +1 -1
  180. package/dist/cjs/core/toolGates.d.ts.map +1 -1
  181. package/dist/cjs/core/toolGates.js +3 -3
  182. package/dist/cjs/core/toolGates.js.map +1 -1
  183. package/dist/cjs/index.d.ts +50 -45
  184. package/dist/cjs/index.d.ts.map +1 -1
  185. package/dist/cjs/index.js +96 -88
  186. package/dist/cjs/index.js.map +1 -1
  187. package/dist/cjs/providers/AnthropicProvider.d.ts +25 -35
  188. package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
  189. package/dist/cjs/providers/AnthropicProvider.js +30 -426
  190. package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
  191. package/dist/cjs/providers/DeepSeekProvider.d.ts +13 -34
  192. package/dist/cjs/providers/DeepSeekProvider.d.ts.map +1 -1
  193. package/dist/cjs/providers/DeepSeekProvider.js +17 -51
  194. package/dist/cjs/providers/DeepSeekProvider.js.map +1 -1
  195. package/dist/cjs/providers/GeminiProvider.d.ts +22 -75
  196. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  197. package/dist/cjs/providers/GeminiProvider.js +32 -558
  198. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  199. package/dist/cjs/providers/GenericOpenAICompatibleProvider.d.ts +9 -10
  200. package/dist/cjs/providers/GenericOpenAICompatibleProvider.d.ts.map +1 -1
  201. package/dist/cjs/providers/GenericOpenAICompatibleProvider.js +14 -20
  202. package/dist/cjs/providers/GenericOpenAICompatibleProvider.js.map +1 -1
  203. package/dist/cjs/providers/OpenAICompatibleProvider.d.ts +26 -135
  204. package/dist/cjs/providers/OpenAICompatibleProvider.d.ts.map +1 -1
  205. package/dist/cjs/providers/OpenAICompatibleProvider.js +40 -496
  206. package/dist/cjs/providers/OpenAICompatibleProvider.js.map +1 -1
  207. package/dist/cjs/providers/OpenAIProvider.d.ts +14 -20
  208. package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
  209. package/dist/cjs/providers/OpenAIProvider.js +21 -28
  210. package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
  211. package/dist/cjs/providers/OpenRouterProvider.d.ts +20 -24
  212. package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
  213. package/dist/cjs/providers/OpenRouterProvider.js +22 -38
  214. package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
  215. package/dist/cjs/providers/ProviderAdapter.d.ts +94 -0
  216. package/dist/cjs/providers/ProviderAdapter.d.ts.map +1 -0
  217. package/dist/cjs/providers/ProviderAdapter.js +257 -0
  218. package/dist/cjs/providers/ProviderAdapter.js.map +1 -0
  219. package/dist/cjs/providers/index.d.ts +21 -18
  220. package/dist/cjs/providers/index.d.ts.map +1 -1
  221. package/dist/cjs/providers/index.js +23 -21
  222. package/dist/cjs/providers/index.js.map +1 -1
  223. package/dist/cjs/types/agent.d.ts +37 -11
  224. package/dist/cjs/types/agent.d.ts.map +1 -1
  225. package/dist/cjs/types/ai.d.ts +11 -21
  226. package/dist/cjs/types/ai.d.ts.map +1 -1
  227. package/dist/cjs/types/compaction.d.ts +2 -2
  228. package/dist/cjs/types/compaction.d.ts.map +1 -1
  229. package/dist/cjs/types/errors.d.ts +16 -20
  230. package/dist/cjs/types/errors.d.ts.map +1 -1
  231. package/dist/cjs/types/errors.js +17 -18
  232. package/dist/cjs/types/errors.js.map +1 -1
  233. package/dist/cjs/types/flow.d.ts +56 -39
  234. package/dist/cjs/types/flow.d.ts.map +1 -1
  235. package/dist/cjs/types/history.d.ts +1 -1
  236. package/dist/cjs/types/history.d.ts.map +1 -1
  237. package/dist/cjs/types/index.d.ts +17 -17
  238. package/dist/cjs/types/index.d.ts.map +1 -1
  239. package/dist/cjs/types/index.js +14 -14
  240. package/dist/cjs/types/index.js.map +1 -1
  241. package/dist/cjs/types/persistence.d.ts +2 -2
  242. package/dist/cjs/types/persistence.d.ts.map +1 -1
  243. package/dist/cjs/types/session.d.ts +4 -4
  244. package/dist/cjs/types/session.d.ts.map +1 -1
  245. package/dist/cjs/types/signals.d.ts +3 -3
  246. package/dist/cjs/types/signals.d.ts.map +1 -1
  247. package/dist/cjs/types/template.d.ts +2 -2
  248. package/dist/cjs/types/template.d.ts.map +1 -1
  249. package/dist/cjs/types/tool.d.ts +4 -2
  250. package/dist/cjs/types/tool.d.ts.map +1 -1
  251. package/dist/cjs/types/tool.js.map +1 -1
  252. package/dist/cjs/utils/condition.d.ts +1 -1
  253. package/dist/cjs/utils/condition.d.ts.map +1 -1
  254. package/dist/cjs/utils/condition.js +6 -6
  255. package/dist/cjs/utils/condition.js.map +1 -1
  256. package/dist/cjs/utils/event.d.ts +1 -1
  257. package/dist/cjs/utils/event.d.ts.map +1 -1
  258. package/dist/cjs/utils/event.js +2 -2
  259. package/dist/cjs/utils/event.js.map +1 -1
  260. package/dist/cjs/utils/history.d.ts +2 -2
  261. package/dist/cjs/utils/history.d.ts.map +1 -1
  262. package/dist/cjs/utils/history.js +15 -15
  263. package/dist/cjs/utils/history.js.map +1 -1
  264. package/dist/cjs/utils/index.d.ts +11 -13
  265. package/dist/cjs/utils/index.d.ts.map +1 -1
  266. package/dist/cjs/utils/index.js +57 -58
  267. package/dist/cjs/utils/index.js.map +1 -1
  268. package/dist/cjs/utils/serialize.d.ts +17 -0
  269. package/dist/cjs/utils/serialize.d.ts.map +1 -1
  270. package/dist/cjs/utils/serialize.js +33 -0
  271. package/dist/cjs/utils/serialize.js.map +1 -1
  272. package/dist/cjs/utils/session.d.ts +23 -3
  273. package/dist/cjs/utils/session.d.ts.map +1 -1
  274. package/dist/cjs/utils/session.js +40 -8
  275. package/dist/cjs/utils/session.js.map +1 -1
  276. package/dist/cjs/utils/template.d.ts +3 -3
  277. package/dist/cjs/utils/template.d.ts.map +1 -1
  278. package/dist/cjs/utils/template.js +5 -5
  279. package/dist/cjs/utils/template.js.map +1 -1
  280. package/dist/constants/index.d.ts +1 -0
  281. package/dist/constants/index.js +1 -1
  282. package/dist/core/Agent.d.ts +19 -11
  283. package/dist/core/Agent.d.ts.map +1 -1
  284. package/dist/core/Agent.js +53 -15
  285. package/dist/core/Agent.js.map +1 -1
  286. package/dist/core/AutoChainExecutor.d.ts +12 -22
  287. package/dist/core/AutoChainExecutor.d.ts.map +1 -1
  288. package/dist/core/AutoChainExecutor.js +27 -30
  289. package/dist/core/AutoChainExecutor.js.map +1 -1
  290. package/dist/core/BranchEvaluator.d.ts +4 -4
  291. package/dist/core/BranchEvaluator.d.ts.map +1 -1
  292. package/dist/core/BranchEvaluator.js +2 -2
  293. package/dist/core/BranchEvaluator.js.map +1 -1
  294. package/dist/core/CompactionEngine.d.ts +16 -3
  295. package/dist/core/CompactionEngine.d.ts.map +1 -1
  296. package/dist/core/CompactionEngine.js +30 -6
  297. package/dist/core/CompactionEngine.js.map +1 -1
  298. package/dist/core/DirectiveChainTracker.d.ts +1 -1
  299. package/dist/core/DirectiveChainTracker.d.ts.map +1 -1
  300. package/dist/core/DirectiveChainTracker.js +2 -2
  301. package/dist/core/DirectiveChainTracker.js.map +1 -1
  302. package/dist/core/Events.d.ts +1 -1
  303. package/dist/core/Events.d.ts.map +1 -1
  304. package/dist/core/Events.js +1 -1
  305. package/dist/core/Events.js.map +1 -1
  306. package/dist/core/Flow.d.ts +4 -4
  307. package/dist/core/Flow.d.ts.map +1 -1
  308. package/dist/core/Flow.js +3 -3
  309. package/dist/core/Flow.js.map +1 -1
  310. package/dist/core/FlowRouter.d.ts +4 -4
  311. package/dist/core/FlowRouter.d.ts.map +1 -1
  312. package/dist/core/FlowRouter.js +36 -14
  313. package/dist/core/FlowRouter.js.map +1 -1
  314. package/dist/core/PersistenceManager.d.ts +1 -1
  315. package/dist/core/PersistenceManager.d.ts.map +1 -1
  316. package/dist/core/PersistenceManager.js +3 -3
  317. package/dist/core/PersistenceManager.js.map +1 -1
  318. package/dist/core/PromptComposer.d.ts +4 -4
  319. package/dist/core/PromptComposer.d.ts.map +1 -1
  320. package/dist/core/PromptComposer.js +3 -3
  321. package/dist/core/PromptComposer.js.map +1 -1
  322. package/dist/core/PromptSectionCache.d.ts +2 -2
  323. package/dist/core/PromptSectionCache.d.ts.map +1 -1
  324. package/dist/core/ResponseEngine.d.ts +4 -4
  325. package/dist/core/ResponseEngine.d.ts.map +1 -1
  326. package/dist/core/ResponseEngine.js +2 -2
  327. package/dist/core/ResponseEngine.js.map +1 -1
  328. package/dist/core/ResponseGenerationError.d.ts.map +1 -1
  329. package/dist/core/ResponseGenerationError.js +3 -5
  330. package/dist/core/ResponseGenerationError.js.map +1 -1
  331. package/dist/core/ResponseModal.d.ts +39 -10
  332. package/dist/core/ResponseModal.d.ts.map +1 -1
  333. package/dist/core/ResponseModal.js +152 -29
  334. package/dist/core/ResponseModal.js.map +1 -1
  335. package/dist/core/ResponsePipeline.d.ts +50 -12
  336. package/dist/core/ResponsePipeline.d.ts.map +1 -1
  337. package/dist/core/ResponsePipeline.js +232 -89
  338. package/dist/core/ResponsePipeline.js.map +1 -1
  339. package/dist/core/SessionFinalizer.d.ts +4 -4
  340. package/dist/core/SessionFinalizer.d.ts.map +1 -1
  341. package/dist/core/SessionFinalizer.js +32 -5
  342. package/dist/core/SessionFinalizer.js.map +1 -1
  343. package/dist/core/SessionManager.d.ts +15 -6
  344. package/dist/core/SessionManager.d.ts.map +1 -1
  345. package/dist/core/SessionManager.js +46 -19
  346. package/dist/core/SessionManager.js.map +1 -1
  347. package/dist/core/SignalCoordinator.d.ts +5 -5
  348. package/dist/core/SignalCoordinator.d.ts.map +1 -1
  349. package/dist/core/SignalCoordinator.js +2 -2
  350. package/dist/core/SignalCoordinator.js.map +1 -1
  351. package/dist/core/SignalEvaluator.d.ts +4 -4
  352. package/dist/core/SignalEvaluator.d.ts.map +1 -1
  353. package/dist/core/SignalEvaluator.js +2 -2
  354. package/dist/core/SignalEvaluator.js.map +1 -1
  355. package/dist/core/SignalProcessor.d.ts +6 -6
  356. package/dist/core/SignalProcessor.d.ts.map +1 -1
  357. package/dist/core/SignalProcessor.js +7 -79
  358. package/dist/core/SignalProcessor.js.map +1 -1
  359. package/dist/core/Step.d.ts +5 -5
  360. package/dist/core/Step.d.ts.map +1 -1
  361. package/dist/core/Step.js +53 -5
  362. package/dist/core/Step.js.map +1 -1
  363. package/dist/core/StepLifecycle.d.ts +18 -8
  364. package/dist/core/StepLifecycle.d.ts.map +1 -1
  365. package/dist/core/StepLifecycle.js +98 -15
  366. package/dist/core/StepLifecycle.js.map +1 -1
  367. package/dist/core/StreamingToolExecutor.d.ts +1 -1
  368. package/dist/core/StreamingToolExecutor.d.ts.map +1 -1
  369. package/dist/core/StreamingToolExecutor.js +29 -5
  370. package/dist/core/StreamingToolExecutor.js.map +1 -1
  371. package/dist/core/ToolLoopExecutor.d.ts +8 -4
  372. package/dist/core/ToolLoopExecutor.d.ts.map +1 -1
  373. package/dist/core/ToolLoopExecutor.js +157 -65
  374. package/dist/core/ToolLoopExecutor.js.map +1 -1
  375. package/dist/core/ToolManager.d.ts +6 -6
  376. package/dist/core/ToolManager.d.ts.map +1 -1
  377. package/dist/core/ToolManager.js +44 -21
  378. package/dist/core/ToolManager.js.map +1 -1
  379. package/dist/core/createAgent.d.ts +2 -2
  380. package/dist/core/createAgent.d.ts.map +1 -1
  381. package/dist/core/createAgent.js +1 -1
  382. package/dist/core/createAgent.js.map +1 -1
  383. package/dist/core/flow-namespace.d.ts +16 -1
  384. package/dist/core/flow-namespace.d.ts.map +1 -1
  385. package/dist/core/flow-namespace.js +23 -1
  386. package/dist/core/flow-namespace.js.map +1 -1
  387. package/dist/core/toolGates.d.ts +1 -1
  388. package/dist/core/toolGates.d.ts.map +1 -1
  389. package/dist/core/toolGates.js +1 -1
  390. package/dist/core/toolGates.js.map +1 -1
  391. package/dist/index.d.ts +50 -45
  392. package/dist/index.d.ts.map +1 -1
  393. package/dist/index.js +34 -30
  394. package/dist/index.js.map +1 -1
  395. package/dist/providers/AnthropicProvider.d.ts +25 -35
  396. package/dist/providers/AnthropicProvider.d.ts.map +1 -1
  397. package/dist/providers/AnthropicProvider.js +30 -423
  398. package/dist/providers/AnthropicProvider.js.map +1 -1
  399. package/dist/providers/DeepSeekProvider.d.ts +13 -34
  400. package/dist/providers/DeepSeekProvider.d.ts.map +1 -1
  401. package/dist/providers/DeepSeekProvider.js +16 -47
  402. package/dist/providers/DeepSeekProvider.js.map +1 -1
  403. package/dist/providers/GeminiProvider.d.ts +22 -75
  404. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  405. package/dist/providers/GeminiProvider.js +32 -558
  406. package/dist/providers/GeminiProvider.js.map +1 -1
  407. package/dist/providers/GenericOpenAICompatibleProvider.d.ts +9 -10
  408. package/dist/providers/GenericOpenAICompatibleProvider.d.ts.map +1 -1
  409. package/dist/providers/GenericOpenAICompatibleProvider.js +13 -16
  410. package/dist/providers/GenericOpenAICompatibleProvider.js.map +1 -1
  411. package/dist/providers/OpenAICompatibleProvider.d.ts +26 -135
  412. package/dist/providers/OpenAICompatibleProvider.d.ts.map +1 -1
  413. package/dist/providers/OpenAICompatibleProvider.js +39 -495
  414. package/dist/providers/OpenAICompatibleProvider.js.map +1 -1
  415. package/dist/providers/OpenAIProvider.d.ts +14 -20
  416. package/dist/providers/OpenAIProvider.d.ts.map +1 -1
  417. package/dist/providers/OpenAIProvider.js +20 -24
  418. package/dist/providers/OpenAIProvider.js.map +1 -1
  419. package/dist/providers/OpenRouterProvider.d.ts +20 -24
  420. package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
  421. package/dist/providers/OpenRouterProvider.js +21 -34
  422. package/dist/providers/OpenRouterProvider.js.map +1 -1
  423. package/dist/providers/ProviderAdapter.d.ts +94 -0
  424. package/dist/providers/ProviderAdapter.d.ts.map +1 -0
  425. package/dist/providers/ProviderAdapter.js +251 -0
  426. package/dist/providers/ProviderAdapter.js.map +1 -0
  427. package/dist/providers/index.d.ts +21 -18
  428. package/dist/providers/index.d.ts.map +1 -1
  429. package/dist/providers/index.js +13 -10
  430. package/dist/providers/index.js.map +1 -1
  431. package/dist/types/agent.d.ts +37 -11
  432. package/dist/types/agent.d.ts.map +1 -1
  433. package/dist/types/ai.d.ts +11 -21
  434. package/dist/types/ai.d.ts.map +1 -1
  435. package/dist/types/compaction.d.ts +2 -2
  436. package/dist/types/compaction.d.ts.map +1 -1
  437. package/dist/types/errors.d.ts +16 -20
  438. package/dist/types/errors.d.ts.map +1 -1
  439. package/dist/types/errors.js +15 -16
  440. package/dist/types/errors.js.map +1 -1
  441. package/dist/types/flow.d.ts +56 -39
  442. package/dist/types/flow.d.ts.map +1 -1
  443. package/dist/types/history.d.ts +1 -1
  444. package/dist/types/history.d.ts.map +1 -1
  445. package/dist/types/index.d.ts +17 -17
  446. package/dist/types/index.d.ts.map +1 -1
  447. package/dist/types/index.js +4 -4
  448. package/dist/types/index.js.map +1 -1
  449. package/dist/types/persistence.d.ts +2 -2
  450. package/dist/types/persistence.d.ts.map +1 -1
  451. package/dist/types/session.d.ts +4 -4
  452. package/dist/types/session.d.ts.map +1 -1
  453. package/dist/types/signals.d.ts +3 -3
  454. package/dist/types/signals.d.ts.map +1 -1
  455. package/dist/types/template.d.ts +2 -2
  456. package/dist/types/template.d.ts.map +1 -1
  457. package/dist/types/tool.d.ts +4 -2
  458. package/dist/types/tool.d.ts.map +1 -1
  459. package/dist/types/tool.js.map +1 -1
  460. package/dist/utils/condition.d.ts +1 -1
  461. package/dist/utils/condition.d.ts.map +1 -1
  462. package/dist/utils/condition.js +2 -2
  463. package/dist/utils/condition.js.map +1 -1
  464. package/dist/utils/event.d.ts +1 -1
  465. package/dist/utils/event.d.ts.map +1 -1
  466. package/dist/utils/event.js +1 -1
  467. package/dist/utils/event.js.map +1 -1
  468. package/dist/utils/history.d.ts +2 -2
  469. package/dist/utils/history.d.ts.map +1 -1
  470. package/dist/utils/history.js +1 -1
  471. package/dist/utils/history.js.map +1 -1
  472. package/dist/utils/index.d.ts +11 -13
  473. package/dist/utils/index.d.ts.map +1 -1
  474. package/dist/utils/index.js +11 -12
  475. package/dist/utils/index.js.map +1 -1
  476. package/dist/utils/serialize.d.ts +17 -0
  477. package/dist/utils/serialize.d.ts.map +1 -1
  478. package/dist/utils/serialize.js +31 -0
  479. package/dist/utils/serialize.js.map +1 -1
  480. package/dist/utils/session.d.ts +23 -3
  481. package/dist/utils/session.d.ts.map +1 -1
  482. package/dist/utils/session.js +35 -6
  483. package/dist/utils/session.js.map +1 -1
  484. package/dist/utils/template.d.ts +3 -3
  485. package/dist/utils/template.d.ts.map +1 -1
  486. package/dist/utils/template.js +1 -1
  487. package/dist/utils/template.js.map +1 -1
  488. package/docs/concepts/architecture.md +3 -3
  489. package/docs/concepts/directives.md +1 -1
  490. package/docs/guides/error-handling.md +46 -45
  491. package/docs/guides/flow-control.md +8 -1
  492. package/docs/guides/instructions.md +15 -6
  493. package/docs/guides/persistence.md +12 -5
  494. package/docs/guides/streaming.md +10 -0
  495. package/docs/migration/README.md +4 -0
  496. package/docs/migration/v2-3-to-v2-4.md +4 -0
  497. package/docs/migration/v2-6-to-v2-7.md +246 -0
  498. package/docs/reference/adapters.md +15 -1
  499. package/docs/reference/branches.md +2 -0
  500. package/docs/reference/create-agent.md +28 -0
  501. package/docs/reference/directive.md +1 -1
  502. package/docs/reference/errors.md +30 -32
  503. package/docs/reference/providers.md +63 -60
  504. package/docs/reference/step.md +28 -21
  505. package/docs/reference/tool.md +14 -5
  506. package/docs/start/02-first-agent.md +8 -4
  507. package/docs/start/03-collect-data.md +19 -10
  508. package/examples/01-quickstart.ts +2 -2
  509. package/examples/02-data-extraction.ts +1 -1
  510. package/examples/03-tools.ts +1 -1
  511. package/examples/04-instructions.ts +2 -2
  512. package/examples/05-branching.ts +3 -3
  513. package/examples/06-flow-control.ts +3 -3
  514. package/examples/07-streaming.ts +1 -1
  515. package/examples/08-persistence.ts +2 -2
  516. package/examples/09-signals.ts +1 -1
  517. package/examples/tsconfig.json +6 -3
  518. package/package.json +9 -7
  519. package/src/adapters/MemoryAdapter.ts +33 -37
  520. package/src/adapters/MongoAdapter.ts +3 -3
  521. package/src/adapters/OpenSearchAdapter.ts +4 -4
  522. package/src/adapters/PostgreSQLAdapter.ts +26 -21
  523. package/src/adapters/PrismaAdapter.ts +4 -4
  524. package/src/adapters/RedisAdapter.ts +84 -37
  525. package/src/adapters/SQLiteAdapter.ts +13 -34
  526. package/src/adapters/index.ts +13 -13
  527. package/src/adapters/sessionRow.ts +57 -0
  528. package/src/core/Agent.ts +64 -18
  529. package/src/core/AutoChainExecutor.ts +44 -57
  530. package/src/core/BranchEvaluator.ts +5 -5
  531. package/src/core/CompactionEngine.ts +42 -8
  532. package/src/core/DirectiveChainTracker.ts +3 -3
  533. package/src/core/Events.ts +2 -2
  534. package/src/core/Flow.ts +9 -9
  535. package/src/core/FlowRouter.ts +46 -20
  536. package/src/core/PersistenceManager.ts +4 -4
  537. package/src/core/PromptComposer.ts +8 -8
  538. package/src/core/PromptSectionCache.ts +2 -2
  539. package/src/core/ResponseEngine.ts +6 -6
  540. package/src/core/ResponseGenerationError.ts +3 -6
  541. package/src/core/ResponseModal.ts +205 -39
  542. package/src/core/ResponsePipeline.ts +301 -107
  543. package/src/core/SessionFinalizer.ts +40 -10
  544. package/src/core/SessionManager.ts +61 -27
  545. package/src/core/SignalCoordinator.ts +7 -7
  546. package/src/core/SignalEvaluator.ts +6 -6
  547. package/src/core/SignalProcessor.ts +13 -93
  548. package/src/core/Step.ts +87 -10
  549. package/src/core/StepLifecycle.ts +129 -26
  550. package/src/core/StreamingToolExecutor.ts +33 -8
  551. package/src/core/ToolLoopExecutor.ts +206 -80
  552. package/src/core/ToolManager.ts +53 -26
  553. package/src/core/createAgent.ts +2 -2
  554. package/src/core/flow-namespace.ts +31 -2
  555. package/src/core/toolGates.ts +2 -2
  556. package/src/index.ts +59 -45
  557. package/src/providers/AnthropicProvider.ts +44 -595
  558. package/src/providers/DeepSeekProvider.ts +27 -92
  559. package/src/providers/GeminiProvider.ts +41 -752
  560. package/src/providers/GenericOpenAICompatibleProvider.ts +19 -27
  561. package/src/providers/OpenAICompatibleProvider.ts +58 -764
  562. package/src/providers/OpenAIProvider.ts +31 -55
  563. package/src/providers/OpenRouterProvider.ts +40 -70
  564. package/src/providers/ProviderAdapter.ts +368 -0
  565. package/src/providers/index.ts +21 -23
  566. package/src/types/agent.ts +36 -11
  567. package/src/types/ai.ts +11 -21
  568. package/src/types/compaction.ts +2 -2
  569. package/src/types/errors.ts +17 -35
  570. package/src/types/flow.ts +44 -46
  571. package/src/types/history.ts +1 -1
  572. package/src/types/index.ts +18 -17
  573. package/src/types/persistence.ts +2 -2
  574. package/src/types/session.ts +4 -4
  575. package/src/types/signals.ts +3 -3
  576. package/src/types/template.ts +2 -2
  577. package/src/types/tool.ts +4 -2
  578. package/src/utils/condition.ts +3 -3
  579. package/src/utils/event.ts +1 -1
  580. package/src/utils/history.ts +3 -3
  581. package/src/utils/index.ts +14 -15
  582. package/src/utils/serialize.ts +38 -0
  583. package/src/utils/session.ts +46 -9
  584. package/src/utils/template.ts +3 -3
  585. package/dist/cjs/core/DirectiveBus.d.ts +0 -88
  586. package/dist/cjs/core/DirectiveBus.d.ts.map +0 -1
  587. package/dist/cjs/core/DirectiveBus.js +0 -196
  588. package/dist/cjs/core/DirectiveBus.js.map +0 -1
  589. package/dist/cjs/providers/errorClassification.d.ts +0 -61
  590. package/dist/cjs/providers/errorClassification.d.ts.map +0 -1
  591. package/dist/cjs/providers/errorClassification.js +0 -123
  592. package/dist/cjs/providers/errorClassification.js.map +0 -1
  593. package/dist/cjs/utils/retry.d.ts +0 -67
  594. package/dist/cjs/utils/retry.d.ts.map +0 -1
  595. package/dist/cjs/utils/retry.js +0 -201
  596. package/dist/cjs/utils/retry.js.map +0 -1
  597. package/dist/core/DirectiveBus.d.ts +0 -88
  598. package/dist/core/DirectiveBus.d.ts.map +0 -1
  599. package/dist/core/DirectiveBus.js +0 -192
  600. package/dist/core/DirectiveBus.js.map +0 -1
  601. package/dist/providers/errorClassification.d.ts +0 -61
  602. package/dist/providers/errorClassification.d.ts.map +0 -1
  603. package/dist/providers/errorClassification.js +0 -116
  604. package/dist/providers/errorClassification.js.map +0 -1
  605. package/dist/utils/retry.d.ts +0 -67
  606. package/dist/utils/retry.d.ts.map +0 -1
  607. package/dist/utils/retry.js +0 -193
  608. package/dist/utils/retry.js.map +0 -1
  609. package/src/core/DirectiveBus.ts +0 -248
  610. package/src/providers/errorClassification.ts +0 -172
  611. package/src/utils/retry.ts +0 -274
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Response processing utilities shared between respond() and respondStream() methods
3
3
  */
4
- import { createSession, enterStep, mergeCollected, logger, historyToEvents, eventsToHistory, getLastMessageFromHistory, } from "../utils";
5
- import { enterFlow } from "../utils/session";
6
- import { createTemplateContext } from "../utils/template";
7
- import { FlowConfigurationError } from "../core/Step";
8
- import { evaluateBranches, createAiConditionEvaluator } from "./BranchEvaluator";
9
- import { DirectiveChainTracker } from "./DirectiveChainTracker";
10
- import { ResponseGenerationError } from "./ResponseGenerationError";
4
+ import { createSession, enterStep, mergeCollected, logger, historyToEvents, eventsToHistory, getLastMessageFromHistory, } from "../utils/index.js";
5
+ import { enterFlow } from "../utils/session.js";
6
+ import { createTemplateContext } from "../utils/template.js";
7
+ import { FlowConfigurationError } from "../core/Step.js";
8
+ import { evaluateBranches, createAiConditionEvaluator } from "./BranchEvaluator.js";
9
+ import { DirectiveChainTracker } from "./DirectiveChainTracker.js";
10
+ import { ResponseGenerationError } from "./ResponseGenerationError.js";
11
11
  /**
12
12
  * Position fields on a Directive that represent a navigation decision.
13
13
  * When any of these is set, the directive "wins" the turn's position decision
@@ -25,6 +25,23 @@ export function hasDirectivePositionField(directive) {
25
25
  return false;
26
26
  return DIRECTIVE_POSITION_FIELDS.some((field) => directive[field] !== undefined);
27
27
  }
28
+ /**
29
+ * Compute the per-key data writes the signal phase applied to a session.
30
+ * The signal phase and routing start from the same input session, so any
31
+ * key whose value differs between the input and the signal output was
32
+ * written by the signal phase alone (handler `updateData` calls).
33
+ */
34
+ function diffSignalDataWrites(before, after) {
35
+ const beforeData = (before ?? {});
36
+ const afterData = (after ?? {});
37
+ const writes = {};
38
+ for (const key of Object.keys(afterData)) {
39
+ if (afterData[key] !== beforeData[key]) {
40
+ writes[key] = afterData[key];
41
+ }
42
+ }
43
+ return writes;
44
+ }
28
45
  /**
29
46
  * Shared response processing logic between respond() and respondStream() methods
30
47
  */
@@ -85,7 +102,7 @@ export class ResponsePipeline {
85
102
  * Handle routing and step selection logic
86
103
  */
87
104
  async handleRoutingAndStepSelection(params) {
88
- const { session, history, context, signal } = params;
105
+ const { session, history, context, signal, allowedFlows } = params;
89
106
  // PHASE 2: ROUTING + STEP SELECTION - Determine which flow and step to use (combined)
90
107
  let selectedFlow;
91
108
  let responseDirectives;
@@ -93,8 +110,19 @@ export class ResponsePipeline {
93
110
  let isFlowComplete = false;
94
111
  let completedFlows = [];
95
112
  let targetSession = session;
113
+ // Flows exited this turn via pendingDirective redirect/reset
114
+ const endedFlows = [];
115
+ let exitPrevFlowId;
116
+ let exitPrevFlowTitle;
117
+ let exitReason;
96
118
  // Get flows early since we need them for pending directives
97
119
  const flows = this.getFlows();
120
+ // Routing candidates may be narrowed for this turn (entry pins); the
121
+ // pendingDirective applier below still resolves targets against the FULL
122
+ // registry so declared redirects always resolve.
123
+ const routingFlows = allowedFlows && allowedFlows.length > 0
124
+ ? flows.filter((f) => allowedFlows.includes(f.id) || allowedFlows.includes(f.title))
125
+ : flows;
98
126
  // Check for pending directive from previous flow completion or external dispatch
99
127
  if (targetSession.pendingDirective) {
100
128
  const directive = targetSession.pendingDirective;
@@ -114,8 +142,15 @@ export class ResponsePipeline {
114
142
  ...targetSession,
115
143
  pendingDirective: nextDirective,
116
144
  };
145
+ // Capture the flow we're leaving so directive-driven exits surface on
146
+ // the response (endedFlows).
147
+ exitPrevFlowId = targetSession.currentFlow?.id;
148
+ exitPrevFlowTitle = exitPrevFlowId
149
+ ? flows.find((f) => f.id === exitPrevFlowId)?.title
150
+ : undefined;
117
151
  // Apply the directive: resolve position field to a flow/step
118
152
  if (directive.goTo) {
153
+ exitReason = 'goto';
119
154
  const flowTarget = typeof directive.goTo === 'string'
120
155
  ? directive.goTo
121
156
  : directive.goTo.flow;
@@ -181,6 +216,7 @@ export class ResponsePipeline {
181
216
  }
182
217
  }
183
218
  else if (directive.reset) {
219
+ exitReason = 'reset';
184
220
  // Reset current flow
185
221
  if (targetSession.currentFlow) {
186
222
  const currentFlow = flows.find(r => r.id === targetSession.currentFlow?.id);
@@ -212,10 +248,16 @@ export class ResponsePipeline {
212
248
  }
213
249
  // Skip FlowRouter.decideFlowAndStep — the directive resolved the position
214
250
  }
215
- // If no pending transition or transition handled, do normal routing
216
- if (flows.length > 0 && !selectedFlow) {
251
+ if (exitReason &&
252
+ exitPrevFlowId &&
253
+ (!selectedFlow || selectedFlow.id !== exitPrevFlowId)) {
254
+ endedFlows.push({ flowId: exitPrevFlowId, title: exitPrevFlowTitle, reason: exitReason });
255
+ }
256
+ // If no pending transition or transition handled, do normal routing.
257
+ // Candidates honor allowedFlows; completion scoring runs over the same set.
258
+ if (routingFlows.length > 0 && !selectedFlow) {
217
259
  const orchestration = await this.flowRouter.decideFlowAndStep({
218
- flows: flows,
260
+ flows: routingFlows,
219
261
  session: targetSession,
220
262
  history,
221
263
  agentOptions: this.options,
@@ -241,15 +283,36 @@ export class ResponsePipeline {
241
283
  session: targetSession,
242
284
  isFlowComplete,
243
285
  completedFlows,
286
+ ...(endedFlows.length > 0 ? { endedFlows } : {}),
244
287
  };
245
288
  }
289
+ /**
290
+ * Combine a routing-derived session with the signal phase's non-position
291
+ * mutations. The routing session is the base — it owns position state AND
292
+ * data merges such as flow initialData and directive-carried writes; the
293
+ * signal phase's mutations (trigger recording under `signals`, handler
294
+ * data writes) are re-applied on top. Both phases start from the same
295
+ * input session, so their mutations cannot silently collide.
296
+ */
297
+ combineRoutingAndSignalSessions(params) {
298
+ const { inputSession, signalSession, routingSession } = params;
299
+ let combined = routingSession;
300
+ if (signalSession.signals !== inputSession.signals) {
301
+ combined = { ...combined, signals: signalSession.signals };
302
+ }
303
+ const signalWrites = diffSignalDataWrites(inputSession.data, signalSession.data);
304
+ if (Object.keys(signalWrites).length > 0) {
305
+ combined = mergeCollected(combined, signalWrites);
306
+ }
307
+ return combined;
308
+ }
246
309
  /**
247
310
  * Determine next step and update session
248
311
  */
249
312
  async determineNextStep(params) {
250
313
  const { selectedFlow, selectedStep, session, isFlowComplete, context, busDirective } = params;
251
314
  if (!selectedFlow) {
252
- return { nextStep: undefined, session };
315
+ return { nextStep: undefined, session, isFlowComplete };
253
316
  }
254
317
  // ─── GUARD: directive bus winner with a position field preempts branches ───
255
318
  // Resolution precedence (design.md): bus > branches > linear > AI.
@@ -258,7 +321,7 @@ export class ResponsePipeline {
258
321
  // branches or linear/AI selection — the caller applies the bus directive.
259
322
  if (hasDirectivePositionField(busDirective)) {
260
323
  logger.debug(`[ResponsePipeline] Directive bus winner has position field — skipping branch evaluation and linear/AI selection`);
261
- return { nextStep: undefined, session };
324
+ return { nextStep: undefined, session, isFlowComplete };
262
325
  }
263
326
  // STEP 1 (Algorithm 1): branches win over linear chain AND flow completion.
264
327
  // Evaluate branches before checking isFlowComplete — a branch can redirect
@@ -270,13 +333,20 @@ export class ResponsePipeline {
270
333
  if (currentStep?.branches && currentStep.branches.length > 0) {
271
334
  const branchResult = await this.evaluateStepBranches(currentStep, selectedFlow, session, context);
272
335
  if (branchResult) {
273
- return branchResult;
336
+ // A branch that resolved a position overrides the router's completion
337
+ // proposal. Without this, a branch that parks on a step of its own
338
+ // flow (`then: '<stepId>'`, `then: { reset: true }`) keeps
339
+ // isFlowComplete=true, the caller drops the step it just resolved,
340
+ // and the turn ends as a silent completion — no LLM call, empty
341
+ // reply, flow marked completed for the rest of the session.
342
+ const resolvedPosition = Boolean(branchResult.nextStep || branchResult.flowChanged);
343
+ return { ...branchResult, isFlowComplete: resolvedPosition ? false : isFlowComplete };
274
344
  }
275
345
  // undefined → fall through to linear/AI selection or flow completion
276
346
  }
277
347
  }
278
348
  if (isFlowComplete) {
279
- return { nextStep: undefined, session };
349
+ return { nextStep: undefined, session, isFlowComplete: true };
280
350
  }
281
351
  let nextStep;
282
352
  // If we have a selected step from the combined routing decision, use it
@@ -315,13 +385,13 @@ export class ResponsePipeline {
315
385
  nextStep = currentStepInstance;
316
386
  }
317
387
  }
318
- return { nextStep, session };
388
+ return { nextStep, session, isFlowComplete: false };
319
389
  }
320
390
  }
321
391
  // Update session with next step
322
392
  const updatedSession = enterStep(session, nextStep.id, nextStep.description);
323
393
  logger.debug(`[ResponsePipeline] Entered step: ${nextStep.id}`);
324
- return { nextStep, session: updatedSession };
394
+ return { nextStep, session: updatedSession, isFlowComplete: false };
325
395
  }
326
396
  /**
327
397
  * Evaluate branches on a step and resolve the `then` value.
@@ -481,17 +551,20 @@ export class ResponsePipeline {
481
551
  // Create a fresh chain tracker for this turn (Requirement 22.1)
482
552
  this.createChainTracker();
483
553
  // ROUTING SKIP OPTIMIZATION (Requirements 20.1, 20.2, 20.3):
484
- // When the current step has collect fields AND pre-extraction populates at least
485
- // one of those fields, skip FlowRouter.decideFlowAndStep for this turn.
486
- const routingSkipResult = await this.attemptRoutingSkipForCollect(params);
487
- if (routingSkipResult) {
554
+ // When the current step has collect fields AND step-scoped pre-extraction
555
+ // populates at least one of those fields, skip FlowRouter.decideFlowAndStep
556
+ // for this turn. The check's extraction result is reused by the fallthrough
557
+ // paths below so a turn costs at most ONE extraction LLM call.
558
+ const routingSkipCheck = await this.attemptRoutingSkipForCollect(params);
559
+ if (routingSkipCheck.skipResult) {
560
+ const skipResult = routingSkipCheck.skipResult;
488
561
  // Even when routing is skipped, run pre-signal phase if processor is present
489
562
  if (this.signalCoordinator.enabled) {
490
563
  const signalResult = await this.signalCoordinator.runPrePhase(params.session, params.context, params.history);
491
564
  // If signal halts, override the routing skip result
492
565
  if (signalResult.mergedDirective?.halt) {
493
566
  return {
494
- ...routingSkipResult,
567
+ ...skipResult,
495
568
  session: signalResult.updatedSession,
496
569
  signalFirings: signalResult.firings,
497
570
  signalHalted: true,
@@ -502,15 +575,20 @@ export class ResponsePipeline {
502
575
  if (hasDirectivePositionField(signalResult.mergedDirective)) {
503
576
  return this.signalCoordinator.applyPositionDirective(signalResult);
504
577
  }
505
- // Non-position directive: propagate for pre-LLM augmentation
578
+ // Non-position directive: keep the skip result (extraction merges,
579
+ // step entry) and re-apply the signal phase's non-position mutations
506
580
  return {
507
- ...routingSkipResult,
508
- session: signalResult.updatedSession,
581
+ ...skipResult,
582
+ session: this.combineRoutingAndSignalSessions({
583
+ inputSession: params.session,
584
+ signalSession: signalResult.updatedSession,
585
+ routingSession: skipResult.session,
586
+ }),
509
587
  signalFirings: signalResult.firings,
510
588
  signalPreDirective: signalResult.mergedDirective || undefined,
511
589
  };
512
590
  }
513
- return routingSkipResult;
591
+ return skipResult;
514
592
  }
515
593
  // ── PARALLEL PRE-SIGNAL PHASE + ROUTING (Algorithm 5) ────────────────
516
594
  // When signalProcessor is present, run pre-signals in parallel with routing.
@@ -524,6 +602,7 @@ export class ResponsePipeline {
524
602
  history: params.history,
525
603
  context: params.context,
526
604
  signal: params.signal,
605
+ allowedFlows: params.allowedFlows,
527
606
  }),
528
607
  ]);
529
608
  // ── Requirement 8.2: halt → discard routing, skip LLM ────────────
@@ -544,38 +623,41 @@ export class ResponsePipeline {
544
623
  }
545
624
  // ── Requirement 8.4: non-position directive → use routing, propagate augmentation ──
546
625
  // ── Requirement 8.5: no directive → use routing as-is ─────────────
547
- let updatedSession = signalResult.updatedSession;
548
- // Apply data/context updates from signal to the routed session
626
+ // Base = routed session (position state AND router data merges such as
627
+ // flow initialData survive); the signal phase's non-position mutations
628
+ // (trigger state, handler data writes) are re-applied on top.
629
+ let updatedSession = this.combineRoutingAndSignalSessions({
630
+ inputSession: params.session,
631
+ signalSession: signalResult.updatedSession,
632
+ routingSession: routingResult.session,
633
+ });
634
+ // Explicit dataUpdate from the signal's merged directive lands last
549
635
  if (signalResult.mergedDirective?.dataUpdate) {
550
636
  updatedSession = mergeCollected(updatedSession, signalResult.mergedDirective.dataUpdate);
551
637
  }
552
- // Use routing result for flow/step, but carry signal session state
553
- // Merge routing session changes on top of signal session
554
- const routingSession = routingResult.session;
555
- updatedSession = {
556
- ...updatedSession,
557
- currentFlow: routingSession.currentFlow,
558
- currentStep: routingSession.currentStep,
559
- flowHistory: routingSession.flowHistory,
560
- pendingDirective: routingSession.pendingDirective,
561
- };
562
638
  const isFlowComplete = routingResult.isFlowComplete;
563
- // PRE-EXTRACTION: same logic as below — extract data from user message
639
+ // PRE-EXTRACTION: same logic as below — extract data from user message.
640
+ // Reuses the routing-skip check's step-scoped extraction when it already
641
+ // ran this turn (at most ONE extraction LLM call per turn).
564
642
  if (routingResult.selectedFlow && !isFlowComplete) {
565
- if (this.shouldPreExtractData(routingResult.selectedFlow)) {
643
+ let extractedData;
644
+ if (routingSkipCheck.extractionRan) {
645
+ extractedData = routingSkipCheck.extractedData;
646
+ }
647
+ else if (this.shouldPreExtractData(routingResult.selectedFlow)) {
566
648
  logger.debug(`[ResponsePipeline] Pre-extracting data for flow: ${routingResult.selectedFlow.title}`);
567
- const extractedData = await this.preExtractFlowData({
649
+ extractedData = await this.preExtractFlowData({
568
650
  route: routingResult.selectedFlow,
569
651
  history: params.history,
570
652
  context: params.context,
571
653
  session: updatedSession,
572
654
  signal: params.signal,
573
655
  });
574
- if (extractedData && Object.keys(extractedData).length > 0) {
575
- logger.debug(`[ResponsePipeline] Pre-extracted data:`, extractedData);
576
- updatedSession = mergeCollected(updatedSession, extractedData);
577
- await this.updateCollectedData(extractedData);
578
- }
656
+ }
657
+ if (extractedData && Object.keys(extractedData).length > 0) {
658
+ logger.debug(`[ResponsePipeline] Pre-extracted data:`, extractedData);
659
+ updatedSession = mergeCollected(updatedSession, extractedData);
660
+ await this.updateCollectedData(extractedData);
579
661
  }
580
662
  }
581
663
  // Determine next step
@@ -591,9 +673,10 @@ export class ResponsePipeline {
591
673
  selectedStep: stepResult.nextStep,
592
674
  responseDirectives: routingResult.responseDirectives,
593
675
  session: stepResult.session,
594
- isFlowComplete: stepResult.flowChanged ? false : isFlowComplete,
676
+ isFlowComplete: stepResult.isFlowComplete,
595
677
  signalFirings: signalResult.firings,
596
678
  signalPreDirective: signalResult.mergedDirective || undefined,
679
+ endedFlows: routingResult.endedFlows,
597
680
  };
598
681
  }
599
682
  // ── No signal processor: existing behavior (zero overhead) ────────────
@@ -602,30 +685,37 @@ export class ResponsePipeline {
602
685
  history: params.history,
603
686
  context: params.context,
604
687
  signal: params.signal,
688
+ allowedFlows: params.allowedFlows,
605
689
  });
606
690
  let updatedSession = routingResult.session;
607
691
  const isFlowComplete = routingResult.isFlowComplete;
608
692
  // PRE-EXTRACTION: If entering a flow that collects data, extract data from user message first
609
- // This allows us to skip steps whose data is already provided
693
+ // This allows us to skip steps whose data is already provided.
694
+ // Reuses the routing-skip check's step-scoped extraction when it already
695
+ // ran this turn — at most ONE extraction LLM call per turn.
610
696
  if (routingResult.selectedFlow && !isFlowComplete) {
611
697
  // Always pre-extract when flow collects data (not just on new flow entry)
612
698
  // This ensures step selection has the most up-to-date data
613
- if (this.shouldPreExtractData(routingResult.selectedFlow)) {
699
+ let extractedData;
700
+ if (routingSkipCheck.extractionRan) {
701
+ extractedData = routingSkipCheck.extractedData;
702
+ }
703
+ else if (this.shouldPreExtractData(routingResult.selectedFlow)) {
614
704
  logger.debug(`[ResponsePipeline] Pre-extracting data for flow: ${routingResult.selectedFlow.title}`);
615
- const extractedData = await this.preExtractFlowData({
705
+ extractedData = await this.preExtractFlowData({
616
706
  route: routingResult.selectedFlow,
617
707
  history: params.history,
618
708
  context: params.context,
619
709
  session: updatedSession,
620
710
  signal: params.signal,
621
711
  });
622
- if (extractedData && Object.keys(extractedData).length > 0) {
623
- logger.debug(`[ResponsePipeline] Pre-extracted data:`, extractedData);
624
- // Merge pre-extracted data into session before step selection
625
- updatedSession = mergeCollected(updatedSession, extractedData);
626
- // Also update agent's collected data
627
- await this.updateCollectedData(extractedData);
628
- }
712
+ }
713
+ if (extractedData && Object.keys(extractedData).length > 0) {
714
+ logger.debug(`[ResponsePipeline] Pre-extracted data:`, extractedData);
715
+ // Merge pre-extracted data into session before step selection
716
+ updatedSession = mergeCollected(updatedSession, extractedData);
717
+ // Also update agent's collected data
718
+ await this.updateCollectedData(extractedData);
629
719
  }
630
720
  }
631
721
  // Determine next step using pipeline method for consistency
@@ -641,8 +731,10 @@ export class ResponsePipeline {
641
731
  selectedStep: stepResult.nextStep, // Use the determined next step
642
732
  responseDirectives: routingResult.responseDirectives,
643
733
  session: stepResult.session,
644
- // If a branch changed the flow, the original isFlowComplete no longer applies
645
- isFlowComplete: stepResult.flowChanged ? false : isFlowComplete,
734
+ // determineNextStep owns the verdict: a branch that resolved a position
735
+ // (new flow, or a step of this one) overrides the router's proposal.
736
+ isFlowComplete: stepResult.isFlowComplete,
737
+ endedFlows: routingResult.endedFlows,
646
738
  };
647
739
  }
648
740
  catch (error) {
@@ -737,61 +829,80 @@ export class ResponsePipeline {
737
829
  return { nextStep, session, flowTransition: false };
738
830
  }
739
831
  /**
740
- * Routing skip optimization (Requirements 20.1, 20.2, 20.3):
741
- * When the current step declares `collect` fields AND pre-extraction populates
742
- * at least one of those fields from the user's message, skip routing for this turn.
832
+ * Routing skip check (Requirements 20.1, 20.2, 20.3):
833
+ * When the current step declares `collect` fields AND step-scoped extraction
834
+ * populates at least one of those fields from the user's message, the caller
835
+ * skips routing for this turn (`skipResult`).
836
+ *
837
+ * The extraction is scoped to EXACTLY this step's collect fields — incidental
838
+ * mentions of other (e.g. other-flow) fields cannot pin the routing decision.
839
+ * It is skipped entirely when every collect field is already populated.
743
840
  *
744
- * Returns the routing result if the skip applies, or undefined to fall through
745
- * to normal routing.
841
+ * Always returns what the check did so the caller can reuse the single
842
+ * extraction result in its normal path instead of extracting twice:
843
+ * - `extractionRan` — whether an extraction LLM call was made this turn.
844
+ * - `extractedData` — that call's result (empty when nothing found / not run).
746
845
  */
747
846
  async attemptRoutingSkipForCollect(params) {
748
847
  const { session } = params;
848
+ const notApplicable = { extractionRan: false, extractedData: {} };
749
849
  // Only applies when we already have a current flow and step
750
850
  if (!session.currentFlow || !session.currentStep) {
751
- return undefined;
851
+ return notApplicable;
752
852
  }
753
853
  // Also skip this optimization if there's a pending directive (it takes priority)
754
854
  if (session.pendingDirective) {
755
- return undefined;
855
+ return notApplicable;
756
856
  }
757
857
  // Look up the actual Flow and Step objects to access `collect`
758
858
  const currentFlow = this.getFlows().find((f) => f.id === session.currentFlow?.id);
759
859
  if (!currentFlow) {
760
- return undefined;
860
+ return notApplicable;
761
861
  }
762
862
  const currentStep = currentFlow.getStep(session.currentStep.id);
763
863
  if (!currentStep || !currentStep.collect || currentStep.collect.length === 0) {
764
- return undefined;
864
+ return notApplicable;
765
865
  }
766
- // We have a step with collect fields. Run pre-extraction to see if the
767
- // user's message populates any of them.
768
866
  const collectFields = currentStep.collect;
867
+ // Every relevant field already set — the skip cannot fire; don't spend
868
+ // an extraction LLM call probing for it.
869
+ const sessionRecord = (session.data ?? {});
870
+ const allPopulated = collectFields.every((field) => {
871
+ const value = sessionRecord[String(field)];
872
+ return value !== undefined && value !== null;
873
+ });
874
+ if (allPopulated) {
875
+ return notApplicable;
876
+ }
769
877
  // Snapshot current data for comparison
770
- const dataBefore = { ...session.data };
771
- // Run pre-extraction against the current flow
878
+ const dataBefore = { ...sessionRecord };
879
+ // Step-scoped pre-extraction: see if the user's message populates any of
880
+ // THIS step's collect fields.
772
881
  const extractedData = await this.preExtractFlowData({
773
882
  route: currentFlow,
774
883
  history: params.history,
775
884
  context: params.context,
776
885
  session,
777
886
  signal: params.signal,
887
+ restrictToFields: collectFields.map(String),
778
888
  });
779
889
  if (!extractedData || Object.keys(extractedData).length === 0) {
780
- return undefined;
890
+ return { extractionRan: true, extractedData: {} };
781
891
  }
782
892
  // Determine which collect fields were newly populated by pre-extraction
893
+ const extractedRecord = extractedData;
783
894
  const populatedCollectFields = [];
784
895
  for (const field of collectFields) {
785
- const key = field;
786
- const hadValue = dataBefore[field] !== undefined && dataBefore[field] !== null;
787
- const hasNewValue = extractedData[field] !== undefined && extractedData[field] !== null;
896
+ const key = String(field);
897
+ const hadValue = dataBefore[key] !== undefined && dataBefore[key] !== null;
898
+ const hasNewValue = extractedRecord[key] !== undefined && extractedRecord[key] !== null;
788
899
  if (hasNewValue && !hadValue) {
789
900
  populatedCollectFields.push(key);
790
901
  }
791
902
  }
792
903
  if (populatedCollectFields.length === 0) {
793
904
  // Pre-extraction didn't populate any declared collect field — no skip
794
- return undefined;
905
+ return { extractionRan: true, extractedData };
795
906
  }
796
907
  // ROUTING SKIP: pre-extraction populated collect fields → retain current flow/step
797
908
  logger.debug(`[ResponsePipeline] Routing skip: pre-extraction populated collect fields [${populatedCollectFields.join(', ')}] for step "${currentStep.id}" — skipping FlowRouter`);
@@ -808,11 +919,15 @@ export class ResponsePipeline {
808
919
  context: params.context,
809
920
  });
810
921
  return {
811
- selectedFlow: stepResult.flowChanged || currentFlow,
812
- selectedStep: stepResult.nextStep,
813
- responseDirectives: undefined,
814
- session: stepResult.session,
815
- isFlowComplete: false,
922
+ extractionRan: true,
923
+ extractedData,
924
+ skipResult: {
925
+ selectedFlow: stepResult.flowChanged || currentFlow,
926
+ selectedStep: stepResult.nextStep,
927
+ responseDirectives: undefined,
928
+ session: stepResult.session,
929
+ isFlowComplete: stepResult.isFlowComplete,
930
+ },
816
931
  };
817
932
  }
818
933
  /**
@@ -831,18 +946,41 @@ export class ResponsePipeline {
831
946
  const hasDataCollectionSteps = steps.some(step => step.collect && step.collect.length > 0);
832
947
  return hasDataCollectionSteps;
833
948
  }
949
+ /**
950
+ * Build an extraction schema limited to the given subset of agent schema
951
+ * fields. Used by the routing-skip probe so only the current step's collect
952
+ * fields are visible to the extractor.
953
+ */
954
+ buildFieldRestrictedSchema(agentSchema, fields) {
955
+ const properties = {};
956
+ for (const field of fields) {
957
+ const prop = agentSchema.properties?.[field];
958
+ if (prop) {
959
+ properties[field] = prop;
960
+ }
961
+ }
962
+ return {
963
+ type: "object",
964
+ description: `Extraction restricted to these fields: ${fields.join(', ')}`,
965
+ properties,
966
+ additionalProperties: false,
967
+ };
968
+ }
834
969
  /**
835
970
  * Pre-extract data from user message when entering a flow
836
971
  * This allows skipping steps whose data is already provided
837
972
  */
838
973
  async preExtractFlowData(params) {
839
- const { route: flow, history, signal } = params;
974
+ const { route: flow, history, signal, restrictToFields } = params;
840
975
  // Build a schema for data extraction based on flow's fields
841
- const extractionSchema = this.getSchema();
842
- if (!extractionSchema) {
976
+ const agentSchema = this.getSchema();
977
+ if (!agentSchema) {
843
978
  logger.warn(`[ResponsePipeline] No schema available for pre-extraction`);
844
979
  return {};
845
980
  }
981
+ const extractionSchema = restrictToFields
982
+ ? this.buildFieldRestrictedSchema(agentSchema, restrictToFields)
983
+ : agentSchema;
846
984
  // Get last user message
847
985
  const lastMessage = getLastMessageFromHistory(history);
848
986
  // Build extraction prompt
@@ -855,11 +993,16 @@ export class ResponsePipeline {
855
993
  `Extract data for these fields if present:`,
856
994
  ];
857
995
  // Add field descriptions
858
- if (flow.requiredFields) {
859
- extractionPrompt.push(`Required fields: ${flow.requiredFields.join(', ')}`);
996
+ if (restrictToFields) {
997
+ extractionPrompt.push(`Only these fields: ${restrictToFields.join(', ')}`);
860
998
  }
861
- if (flow.optionalFields) {
862
- extractionPrompt.push(`Optional fields: ${flow.optionalFields.join(', ')}`);
999
+ else {
1000
+ if (flow.requiredFields) {
1001
+ extractionPrompt.push(`Required fields: ${flow.requiredFields.join(', ')}`);
1002
+ }
1003
+ if (flow.optionalFields) {
1004
+ extractionPrompt.push(`Optional fields: ${flow.optionalFields.join(', ')}`);
1005
+ }
863
1006
  }
864
1007
  extractionPrompt.push(``, `Return ONLY the extracted data as JSON. If no data can be extracted, return an empty object {}.`);
865
1008
  // Convert Event[] to HistoryItem[] for provider call