@falai/agent 1.2.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) 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/types/agent.d.ts +183 -54
  126. package/dist/cjs/types/agent.d.ts.map +1 -1
  127. package/dist/cjs/types/agent.js +0 -6
  128. package/dist/cjs/types/agent.js.map +1 -1
  129. package/dist/cjs/types/ai.d.ts +3 -3
  130. package/dist/cjs/types/ai.d.ts.map +1 -1
  131. package/dist/cjs/types/errors.d.ts +15 -0
  132. package/dist/cjs/types/errors.d.ts.map +1 -0
  133. package/dist/cjs/types/errors.js +22 -0
  134. package/dist/cjs/types/errors.js.map +1 -0
  135. package/dist/cjs/types/flow.d.ts +513 -0
  136. package/dist/cjs/types/flow.d.ts.map +1 -0
  137. package/dist/cjs/types/{route.js → flow.js} +2 -2
  138. package/dist/cjs/types/flow.js.map +1 -0
  139. package/dist/cjs/types/index.d.ts +7 -6
  140. package/dist/cjs/types/index.d.ts.map +1 -1
  141. package/dist/cjs/types/index.js +6 -2
  142. package/dist/cjs/types/index.js.map +1 -1
  143. package/dist/cjs/types/persistence.d.ts +11 -7
  144. package/dist/cjs/types/persistence.d.ts.map +1 -1
  145. package/dist/cjs/types/routing.d.ts +1 -1
  146. package/dist/cjs/types/routing.d.ts.map +1 -1
  147. package/dist/cjs/types/session.d.ts +24 -23
  148. package/dist/cjs/types/session.d.ts.map +1 -1
  149. package/dist/cjs/types/signals.d.ts +248 -0
  150. package/dist/cjs/types/signals.d.ts.map +1 -0
  151. package/dist/cjs/types/signals.js +11 -0
  152. package/dist/cjs/types/signals.js.map +1 -0
  153. package/dist/cjs/types/template.d.ts +2 -8
  154. package/dist/cjs/types/template.d.ts.map +1 -1
  155. package/dist/cjs/types/tool.d.ts +36 -29
  156. package/dist/cjs/types/tool.d.ts.map +1 -1
  157. package/dist/cjs/types/tool.js +1 -1
  158. package/dist/cjs/types/tool.js.map +1 -1
  159. package/dist/cjs/utils/condition.d.ts +7 -1
  160. package/dist/cjs/utils/condition.d.ts.map +1 -1
  161. package/dist/cjs/utils/condition.js.map +1 -1
  162. package/dist/cjs/utils/id.d.ts +13 -5
  163. package/dist/cjs/utils/id.d.ts.map +1 -1
  164. package/dist/cjs/utils/id.js +24 -10
  165. package/dist/cjs/utils/id.js.map +1 -1
  166. package/dist/cjs/utils/index.d.ts +2 -2
  167. package/dist/cjs/utils/index.d.ts.map +1 -1
  168. package/dist/cjs/utils/index.js +7 -3
  169. package/dist/cjs/utils/index.js.map +1 -1
  170. package/dist/cjs/utils/session.d.ts +44 -5
  171. package/dist/cjs/utils/session.d.ts.map +1 -1
  172. package/dist/cjs/utils/session.js +197 -38
  173. package/dist/cjs/utils/session.js.map +1 -1
  174. package/dist/constants/index.d.ts +0 -9
  175. package/dist/constants/index.d.ts.map +1 -1
  176. package/dist/constants/index.js +3 -9
  177. package/dist/constants/index.js.map +1 -1
  178. package/dist/core/Agent.d.ts +119 -153
  179. package/dist/core/Agent.d.ts.map +1 -1
  180. package/dist/core/Agent.js +472 -325
  181. package/dist/core/Agent.js.map +1 -1
  182. package/dist/core/AutoChainExecutor.d.ts +107 -0
  183. package/dist/core/AutoChainExecutor.d.ts.map +1 -0
  184. package/dist/core/AutoChainExecutor.js +293 -0
  185. package/dist/core/AutoChainExecutor.js.map +1 -0
  186. package/dist/core/BranchEvaluator.d.ts +54 -0
  187. package/dist/core/BranchEvaluator.d.ts.map +1 -0
  188. package/dist/core/BranchEvaluator.js +126 -0
  189. package/dist/core/BranchEvaluator.js.map +1 -0
  190. package/dist/core/DirectiveBus.d.ts +88 -0
  191. package/dist/core/DirectiveBus.d.ts.map +1 -0
  192. package/dist/core/DirectiveBus.js +192 -0
  193. package/dist/core/DirectiveBus.js.map +1 -0
  194. package/dist/core/DirectiveChainTracker.d.ts +49 -0
  195. package/dist/core/DirectiveChainTracker.d.ts.map +1 -0
  196. package/dist/core/DirectiveChainTracker.js +117 -0
  197. package/dist/core/DirectiveChainTracker.js.map +1 -0
  198. package/dist/core/Flow.d.ts +186 -0
  199. package/dist/core/Flow.d.ts.map +1 -0
  200. package/dist/core/Flow.js +546 -0
  201. package/dist/core/Flow.js.map +1 -0
  202. package/dist/core/FlowRouter.d.ts +182 -0
  203. package/dist/core/FlowRouter.d.ts.map +1 -0
  204. package/dist/core/{RoutingEngine.js → FlowRouter.js} +322 -305
  205. package/dist/core/FlowRouter.js.map +1 -0
  206. package/dist/core/PersistenceManager.d.ts +2 -2
  207. package/dist/core/PersistenceManager.d.ts.map +1 -1
  208. package/dist/core/PersistenceManager.js +7 -7
  209. package/dist/core/PersistenceManager.js.map +1 -1
  210. package/dist/core/PromptComposer.d.ts +21 -8
  211. package/dist/core/PromptComposer.d.ts.map +1 -1
  212. package/dist/core/PromptComposer.js +183 -106
  213. package/dist/core/PromptComposer.js.map +1 -1
  214. package/dist/core/PromptSectionCache.d.ts +1 -1
  215. package/dist/core/PromptSectionCache.js +1 -1
  216. package/dist/core/ResponseEngine.d.ts +18 -8
  217. package/dist/core/ResponseEngine.d.ts.map +1 -1
  218. package/dist/core/ResponseEngine.js +38 -36
  219. package/dist/core/ResponseEngine.js.map +1 -1
  220. package/dist/core/ResponseModal.d.ts +73 -56
  221. package/dist/core/ResponseModal.d.ts.map +1 -1
  222. package/dist/core/ResponseModal.js +1193 -1016
  223. package/dist/core/ResponseModal.js.map +1 -1
  224. package/dist/core/ResponsePipeline.d.ts +124 -26
  225. package/dist/core/ResponsePipeline.d.ts.map +1 -1
  226. package/dist/core/ResponsePipeline.js +509 -137
  227. package/dist/core/ResponsePipeline.js.map +1 -1
  228. package/dist/core/SignalEvaluator.d.ts +86 -0
  229. package/dist/core/SignalEvaluator.d.ts.map +1 -0
  230. package/dist/core/SignalEvaluator.js +326 -0
  231. package/dist/core/SignalEvaluator.js.map +1 -0
  232. package/dist/core/SignalProcessor.d.ts +152 -0
  233. package/dist/core/SignalProcessor.d.ts.map +1 -0
  234. package/dist/core/SignalProcessor.js +555 -0
  235. package/dist/core/SignalProcessor.js.map +1 -0
  236. package/dist/core/Step.d.ts +43 -32
  237. package/dist/core/Step.d.ts.map +1 -1
  238. package/dist/core/Step.js +220 -126
  239. package/dist/core/Step.js.map +1 -1
  240. package/dist/core/StreamingToolExecutor.d.ts +2 -2
  241. package/dist/core/StreamingToolExecutor.d.ts.map +1 -1
  242. package/dist/core/StreamingToolExecutor.js.map +1 -1
  243. package/dist/core/ToolManager.d.ts +44 -13
  244. package/dist/core/ToolManager.d.ts.map +1 -1
  245. package/dist/core/ToolManager.js +174 -91
  246. package/dist/core/ToolManager.js.map +1 -1
  247. package/dist/core/createAgent.d.ts +35 -0
  248. package/dist/core/createAgent.d.ts.map +1 -0
  249. package/dist/core/createAgent.js +36 -0
  250. package/dist/core/createAgent.js.map +1 -0
  251. package/dist/core/flow-namespace.d.ts +49 -0
  252. package/dist/core/flow-namespace.d.ts.map +1 -0
  253. package/dist/core/flow-namespace.js +168 -0
  254. package/dist/core/flow-namespace.js.map +1 -0
  255. package/dist/index.d.ts +11 -14
  256. package/dist/index.d.ts.map +1 -1
  257. package/dist/index.js +9 -12
  258. package/dist/index.js.map +1 -1
  259. package/dist/types/agent.d.ts +183 -54
  260. package/dist/types/agent.d.ts.map +1 -1
  261. package/dist/types/agent.js +0 -6
  262. package/dist/types/agent.js.map +1 -1
  263. package/dist/types/ai.d.ts +3 -3
  264. package/dist/types/ai.d.ts.map +1 -1
  265. package/dist/types/errors.d.ts +15 -0
  266. package/dist/types/errors.d.ts.map +1 -0
  267. package/dist/types/errors.js +18 -0
  268. package/dist/types/errors.js.map +1 -0
  269. package/dist/types/flow.d.ts +513 -0
  270. package/dist/types/flow.d.ts.map +1 -0
  271. package/dist/types/flow.js +5 -0
  272. package/dist/types/flow.js.map +1 -0
  273. package/dist/types/index.d.ts +7 -6
  274. package/dist/types/index.d.ts.map +1 -1
  275. package/dist/types/index.js +4 -1
  276. package/dist/types/index.js.map +1 -1
  277. package/dist/types/persistence.d.ts +11 -7
  278. package/dist/types/persistence.d.ts.map +1 -1
  279. package/dist/types/routing.d.ts +1 -1
  280. package/dist/types/routing.d.ts.map +1 -1
  281. package/dist/types/session.d.ts +24 -23
  282. package/dist/types/session.d.ts.map +1 -1
  283. package/dist/types/signals.d.ts +248 -0
  284. package/dist/types/signals.d.ts.map +1 -0
  285. package/dist/types/signals.js +10 -0
  286. package/dist/types/signals.js.map +1 -0
  287. package/dist/types/template.d.ts +2 -8
  288. package/dist/types/template.d.ts.map +1 -1
  289. package/dist/types/tool.d.ts +36 -29
  290. package/dist/types/tool.d.ts.map +1 -1
  291. package/dist/types/tool.js +1 -1
  292. package/dist/types/tool.js.map +1 -1
  293. package/dist/utils/condition.d.ts +7 -1
  294. package/dist/utils/condition.d.ts.map +1 -1
  295. package/dist/utils/condition.js.map +1 -1
  296. package/dist/utils/id.d.ts +13 -5
  297. package/dist/utils/id.d.ts.map +1 -1
  298. package/dist/utils/id.js +22 -9
  299. package/dist/utils/id.js.map +1 -1
  300. package/dist/utils/index.d.ts +2 -2
  301. package/dist/utils/index.d.ts.map +1 -1
  302. package/dist/utils/index.js +2 -2
  303. package/dist/utils/index.js.map +1 -1
  304. package/dist/utils/session.d.ts +44 -5
  305. package/dist/utils/session.d.ts.map +1 -1
  306. package/dist/utils/session.js +193 -37
  307. package/dist/utils/session.js.map +1 -1
  308. package/docs/README.md +15 -202
  309. package/docs/concepts/architecture.md +281 -0
  310. package/docs/concepts/directives.md +400 -0
  311. package/docs/concepts/pipeline.md +399 -0
  312. package/docs/guides/branching.md +263 -0
  313. package/docs/guides/compaction.md +163 -0
  314. package/docs/guides/conditions.md +167 -0
  315. package/docs/guides/error-handling.md +176 -0
  316. package/docs/guides/flow-control.md +409 -0
  317. package/docs/guides/instructions.md +210 -0
  318. package/docs/guides/persistence.md +182 -0
  319. package/docs/guides/streaming.md +137 -0
  320. package/docs/migration/README.md +15 -0
  321. package/docs/migration/route-to-flow.md +560 -0
  322. package/docs/migration/v1-to-v2.md +909 -0
  323. package/docs/reference/adapters.md +481 -0
  324. package/docs/reference/branches.md +241 -0
  325. package/docs/reference/create-agent.md +186 -0
  326. package/docs/reference/directive.md +243 -0
  327. package/docs/reference/errors.md +122 -0
  328. package/docs/reference/flow.md +238 -0
  329. package/docs/reference/instruction.md +177 -0
  330. package/docs/reference/pre-directive.md +131 -0
  331. package/docs/reference/providers.md +227 -0
  332. package/docs/reference/signals.md +356 -0
  333. package/docs/reference/step.md +339 -0
  334. package/docs/reference/tool.md +269 -0
  335. package/docs/start/01-install.md +81 -0
  336. package/docs/start/02-first-agent.md +196 -0
  337. package/docs/start/03-collect-data.md +222 -0
  338. package/docs/start/04-add-tools.md +276 -0
  339. package/docs/start/05-go-to-production.md +216 -0
  340. package/examples/01-quickstart.ts +20 -0
  341. package/examples/02-data-extraction.ts +90 -0
  342. package/examples/03-tools.ts +136 -0
  343. package/examples/04-instructions.ts +100 -0
  344. package/examples/05-branching.ts +140 -0
  345. package/examples/06-flow-control.ts +103 -0
  346. package/examples/07-streaming.ts +69 -0
  347. package/examples/08-persistence.ts +98 -0
  348. package/examples/09-signals.ts +144 -0
  349. package/examples/tsconfig.json +30 -0
  350. package/package.json +2 -1
  351. package/src/adapters/MemoryAdapter.ts +3 -3
  352. package/src/adapters/MongoAdapter.ts +3 -3
  353. package/src/adapters/OpenSearchAdapter.ts +10 -8
  354. package/src/adapters/PostgreSQLAdapter.ts +26 -10
  355. package/src/adapters/PrismaAdapter.ts +6 -6
  356. package/src/adapters/RedisAdapter.ts +3 -3
  357. package/src/adapters/SQLiteAdapter.ts +31 -12
  358. package/src/constants/index.ts +2 -10
  359. package/src/core/Agent.ts +585 -374
  360. package/src/core/AutoChainExecutor.ts +440 -0
  361. package/src/core/BranchEvaluator.ts +167 -0
  362. package/src/core/DirectiveBus.ts +248 -0
  363. package/src/core/DirectiveChainTracker.ts +144 -0
  364. package/src/core/Flow.ts +666 -0
  365. package/src/core/{RoutingEngine.ts → FlowRouter.ts} +385 -365
  366. package/src/core/PersistenceManager.ts +8 -8
  367. package/src/core/PromptComposer.ts +209 -140
  368. package/src/core/PromptSectionCache.ts +1 -1
  369. package/src/core/ResponseEngine.ts +61 -46
  370. package/src/core/ResponseModal.ts +1453 -1240
  371. package/src/core/ResponsePipeline.ts +655 -175
  372. package/src/core/SignalEvaluator.ts +420 -0
  373. package/src/core/SignalProcessor.ts +723 -0
  374. package/src/core/Step.ts +279 -176
  375. package/src/core/StreamingToolExecutor.ts +4 -4
  376. package/src/core/ToolManager.ts +200 -97
  377. package/src/core/createAgent.ts +40 -0
  378. package/src/core/flow-namespace.ts +219 -0
  379. package/src/index.ts +42 -36
  380. package/src/types/agent.ts +182 -53
  381. package/src/types/ai.ts +3 -3
  382. package/src/types/errors.ts +18 -0
  383. package/src/types/flow.ts +590 -0
  384. package/src/types/index.ts +43 -16
  385. package/src/types/persistence.ts +12 -8
  386. package/src/types/routing.ts +1 -1
  387. package/src/types/session.ts +26 -23
  388. package/src/types/signals.ts +321 -0
  389. package/src/types/template.ts +3 -11
  390. package/src/types/tool.ts +50 -42
  391. package/src/utils/condition.ts +13 -4
  392. package/src/utils/id.ts +27 -9
  393. package/src/utils/index.ts +6 -2
  394. package/src/utils/session.ts +238 -42
  395. package/dist/cjs/core/BatchExecutor.d.ts +0 -359
  396. package/dist/cjs/core/BatchExecutor.d.ts.map +0 -1
  397. package/dist/cjs/core/BatchExecutor.js +0 -861
  398. package/dist/cjs/core/BatchExecutor.js.map +0 -1
  399. package/dist/cjs/core/BatchPromptBuilder.d.ts +0 -89
  400. package/dist/cjs/core/BatchPromptBuilder.d.ts.map +0 -1
  401. package/dist/cjs/core/BatchPromptBuilder.js +0 -223
  402. package/dist/cjs/core/BatchPromptBuilder.js.map +0 -1
  403. package/dist/cjs/core/Route.d.ts +0 -180
  404. package/dist/cjs/core/Route.d.ts.map +0 -1
  405. package/dist/cjs/core/Route.js +0 -542
  406. package/dist/cjs/core/Route.js.map +0 -1
  407. package/dist/cjs/core/RoutingEngine.d.ts +0 -185
  408. package/dist/cjs/core/RoutingEngine.d.ts.map +0 -1
  409. package/dist/cjs/core/RoutingEngine.js.map +0 -1
  410. package/dist/cjs/types/route.d.ts +0 -336
  411. package/dist/cjs/types/route.d.ts.map +0 -1
  412. package/dist/cjs/types/route.js.map +0 -1
  413. package/dist/core/BatchExecutor.d.ts +0 -359
  414. package/dist/core/BatchExecutor.d.ts.map +0 -1
  415. package/dist/core/BatchExecutor.js +0 -856
  416. package/dist/core/BatchExecutor.js.map +0 -1
  417. package/dist/core/BatchPromptBuilder.d.ts +0 -89
  418. package/dist/core/BatchPromptBuilder.d.ts.map +0 -1
  419. package/dist/core/BatchPromptBuilder.js +0 -219
  420. package/dist/core/BatchPromptBuilder.js.map +0 -1
  421. package/dist/core/Route.d.ts +0 -180
  422. package/dist/core/Route.d.ts.map +0 -1
  423. package/dist/core/Route.js +0 -538
  424. package/dist/core/Route.js.map +0 -1
  425. package/dist/core/RoutingEngine.d.ts +0 -185
  426. package/dist/core/RoutingEngine.d.ts.map +0 -1
  427. package/dist/core/RoutingEngine.js.map +0 -1
  428. package/dist/types/route.d.ts +0 -336
  429. package/dist/types/route.d.ts.map +0 -1
  430. package/dist/types/route.js +0 -5
  431. package/dist/types/route.js.map +0 -1
  432. package/docs/CONTRIBUTING.md +0 -521
  433. package/docs/api/README.md +0 -3299
  434. package/docs/api/overview.md +0 -1410
  435. package/docs/architecture/data-extraction-flow.md +0 -360
  436. package/docs/architecture/multi-step-execution.md +0 -277
  437. package/docs/core/agent/README.md +0 -938
  438. package/docs/core/agent/context-management.md +0 -796
  439. package/docs/core/agent/rules-and-prohibitions.md +0 -113
  440. package/docs/core/agent/session-management.md +0 -693
  441. package/docs/core/ai-integration/prompt-composition.md +0 -355
  442. package/docs/core/ai-integration/providers.md +0 -515
  443. package/docs/core/ai-integration/response-processing.md +0 -433
  444. package/docs/core/conversation-flows/data-collection.md +0 -772
  445. package/docs/core/conversation-flows/route-dsl.md +0 -509
  446. package/docs/core/conversation-flows/routes.md +0 -249
  447. package/docs/core/conversation-flows/step-transitions.md +0 -731
  448. package/docs/core/conversation-flows/steps.md +0 -268
  449. package/docs/core/error-handling.md +0 -830
  450. package/docs/core/persistence/adapters.md +0 -255
  451. package/docs/core/persistence/session-storage.md +0 -656
  452. package/docs/core/routing/intelligent-routing.md +0 -470
  453. package/docs/core/tools/enhanced-tool.md +0 -186
  454. package/docs/core/tools/streaming-execution.md +0 -161
  455. package/docs/core/tools/tool-definition.md +0 -970
  456. package/docs/core/tools/tool-scoping.md +0 -819
  457. package/docs/guides/advanced-patterns/publishing.md +0 -186
  458. package/docs/guides/context-compaction.md +0 -96
  459. package/docs/guides/error-handling-patterns.md +0 -578
  460. package/docs/guides/getting-started/README.md +0 -795
  461. package/docs/guides/migration/README.md +0 -101
  462. package/docs/guides/migration/flexible-routing-conditions.md +0 -375
  463. package/docs/guides/migration/multi-step-execution.md +0 -393
  464. package/docs/guides/migration/response-modal-refactor.md +0 -518
  465. package/docs/guides/prompt-optimization.md +0 -164
  466. package/examples/advanced-patterns/context-compaction.ts +0 -223
  467. package/examples/advanced-patterns/knowledge-based-agent.ts +0 -735
  468. package/examples/advanced-patterns/persistent-onboarding.ts +0 -728
  469. package/examples/advanced-patterns/route-lifecycle-hooks.ts +0 -556
  470. package/examples/advanced-patterns/streaming-responses.ts +0 -656
  471. package/examples/ai-providers/anthropic-integration.ts +0 -388
  472. package/examples/ai-providers/openai-integration.ts +0 -228
  473. package/examples/condition-patterns/function-only-conditions.ts +0 -365
  474. package/examples/condition-patterns/mixed-array-conditions.ts +0 -477
  475. package/examples/condition-patterns/route-skipif-patterns.ts +0 -468
  476. package/examples/condition-patterns/step-skipif-patterns.ts +0 -0
  477. package/examples/condition-patterns/string-only-conditions.ts +0 -296
  478. package/examples/conversation-flows/completion-transitions.ts +0 -318
  479. package/examples/core-concepts/basic-agent.ts +0 -503
  480. package/examples/core-concepts/modern-streaming-api.ts +0 -309
  481. package/examples/core-concepts/schema-driven-extraction.ts +0 -332
  482. package/examples/core-concepts/session-management.ts +0 -494
  483. package/examples/integrations/database-integration.ts +0 -631
  484. package/examples/integrations/healthcare-integration.ts +0 -595
  485. package/examples/integrations/search-integration.ts +0 -530
  486. package/examples/integrations/server-session-management.ts +0 -307
  487. package/examples/persistence/custom-adapter.ts +0 -526
  488. package/examples/persistence/database-persistence.ts +0 -583
  489. package/examples/persistence/memory-sessions.ts +0 -495
  490. package/examples/persistence/prisma-schema.example.prisma +0 -74
  491. package/examples/persistence/redis-persistence.ts +0 -488
  492. package/examples/tools/basic-tools.ts +0 -765
  493. package/examples/tools/data-enrichment-tools.ts +0 -593
  494. package/examples/tools/enhanced-tool-metadata.ts +0 -268
  495. package/examples/tools/streaming-tool-execution.ts +0 -283
  496. package/src/core/BatchExecutor.ts +0 -1187
  497. package/src/core/BatchPromptBuilder.ts +0 -299
  498. package/src/core/Route.ts +0 -678
  499. package/src/types/route.ts +0 -392
@@ -0,0 +1,440 @@
1
+ /**
2
+ * Auto-step chain executor.
3
+ *
4
+ * Walks consecutive `auto: true` steps in a single turn without making LLM calls.
5
+ * Each auto-step runs its pre-LLM hooks (onEnter, prepare), evaluates skipIf/requires,
6
+ * applies state writes, resolves branches, and advances to the next step.
7
+ *
8
+ * The chain terminates when:
9
+ * - An interactive step (auto !== true) is reached → returned as `resolvedStep`
10
+ * - A `prepare` returns `{ halt: true, reply? }` → turn ends with verbatim reply
11
+ * - A position-changing directive (goTo, goToStep, complete) is returned
12
+ * - The last auto-step has no successor → flow is complete
13
+ * - The chain exceeds `maxAutoStepsPerTurn` → throws FlowConfigurationError
14
+ *
15
+ * Implements Algorithm 1 from `.kiro/specs/auto-steps/design.md`.
16
+ */
17
+
18
+ import type { SessionState } from "../types";
19
+ import type { Event } from "../types/history";
20
+ import { FlowConfigurationError, Step } from "./Step";
21
+ import { Flow } from "./Flow";
22
+ import { enterStep, mergeCollected, logger } from "../utils";
23
+ import { createTemplateContext } from "../utils/template";
24
+ import type { StoppedReason } from "../types/flow";
25
+
26
+ /**
27
+ * The directive-like object that `prepare` may return on auto-steps.
28
+ * This is a structural subset of the full PreDirective that v2 will formalize.
29
+ */
30
+ export interface AutoStepPrepareResult {
31
+ dataUpdate?: Record<string, unknown>;
32
+ contextUpdate?: Record<string, unknown>;
33
+ halt?: boolean;
34
+ reply?: string;
35
+ /** Position-changing: jump to a step within the current flow. */
36
+ goToStep?: string;
37
+ /** Position-changing: jump to another flow. */
38
+ goTo?: string;
39
+ /** Position-changing: mark the flow as complete. */
40
+ complete?: boolean;
41
+ }
42
+
43
+ /**
44
+ * A branch predicate context passed to `if` functions.
45
+ */
46
+ interface BranchPredicateContext<TContext, TData> {
47
+ data: Partial<TData> | undefined;
48
+ context: TContext;
49
+ session: SessionState<TData>;
50
+ history: Event[];
51
+ }
52
+
53
+ /**
54
+ * A branch `then` target — either a string step/flow id or a directive object.
55
+ */
56
+ type BranchThen = string | { goToStep?: string; goTo?: string } | undefined;
57
+
58
+ /**
59
+ * A branch entry on a step. Supports code predicates (`if`), AI predicates (`when`),
60
+ * and a target (`then`).
61
+ */
62
+ interface BranchEntry<TContext, TData> {
63
+ if?: ((ctx: BranchPredicateContext<TContext, TData>) => boolean | Promise<boolean>) | Array<(ctx: BranchPredicateContext<TContext, TData>) => boolean | Promise<boolean>>;
64
+ when?: string;
65
+ then?: BranchThen;
66
+ }
67
+
68
+ /**
69
+ * Structural type for a step that may have branches (accessed via cast).
70
+ */
71
+ interface StepWithBranches<TContext, TData> {
72
+ branches?: BranchEntry<TContext, TData>[];
73
+ onEnter?: (context: TContext, data: Partial<TData> | undefined) => Promise<unknown>;
74
+ }
75
+
76
+ /**
77
+ * Result of running the auto-chain.
78
+ */
79
+ export interface AutoChainResult<TContext = unknown, TData = unknown> {
80
+ /** The interactive step to hand off to the LLM path (undefined if chain ended without one). */
81
+ resolvedStep?: Step<TContext, TData>;
82
+ /** The merged directive from the halting auto-step's prepare (only set when stoppedReason = 'halt'). */
83
+ mergedDirective?: AutoStepPrepareResult;
84
+ /** Why the chain stopped, if it didn't reach an interactive step normally. */
85
+ stoppedReason?: StoppedReason;
86
+ /** Updated session after all auto-step state writes. */
87
+ session: SessionState<TData>;
88
+ }
89
+
90
+ /**
91
+ * Configuration for AutoChainExecutor.
92
+ */
93
+ export interface AutoChainExecutorOptions {
94
+ /** Maximum number of auto-steps walked in a single turn before throwing. */
95
+ maxAutoStepsPerTurn: number;
96
+ }
97
+
98
+ /**
99
+ * Parameters for a single chain run.
100
+ */
101
+ export interface AutoChainRunParams<TContext, TData> {
102
+ session: SessionState<TData>;
103
+ context: TContext;
104
+ flow: Flow<TContext, TData>;
105
+ /** Conversation history (used for branch predicate context). Optional. */
106
+ history?: Event[];
107
+ }
108
+
109
+ /**
110
+ * Executes the auto-step chain for a single turn.
111
+ *
112
+ * Algorithm 1 from design.md — walks while `currentStep.auto === true`,
113
+ * executing skipIf → requires → onEnter/prepare → state writes →
114
+ * halt check → position directives → branches → linear advance.
115
+ */
116
+ export class AutoChainExecutor<TContext = unknown, TData = unknown> {
117
+ constructor(private readonly options: AutoChainExecutorOptions) { }
118
+
119
+ /**
120
+ * Run the auto-step chain starting from the current step on the session.
121
+ */
122
+ async run(params: AutoChainRunParams<TContext, TData>): Promise<AutoChainResult<TContext, TData>> {
123
+ const { context, flow, history = [] } = params;
124
+ const { maxAutoStepsPerTurn } = this.options;
125
+ let { session } = params;
126
+ const visited: string[] = [];
127
+
128
+ while (true) {
129
+ // Resolve the current step from session
130
+ const currentStepId = session.currentStep?.id;
131
+ if (!currentStepId) {
132
+ // No current step — nothing to walk. Return undefined resolvedStep.
133
+ return { session };
134
+ }
135
+
136
+ const step = flow.getStep(currentStepId);
137
+ if (!step) {
138
+ // Step not found in flow — shouldn't happen, but bail gracefully.
139
+ return { session };
140
+ }
141
+
142
+ // If the step is not auto, hand off to the interactive path
143
+ if (!step.auto) {
144
+ return { resolvedStep: step, session };
145
+ }
146
+
147
+ // Track visited steps for cap/cycle detection
148
+ visited.push(step.id);
149
+ if (visited.length > maxAutoStepsPerTurn) {
150
+ throw new FlowConfigurationError(
151
+ `[FlowConfigurationError] Auto-step chain exceeded limit: visited ${visited.length} steps which exceeds maxAutoStepsPerTurn (${maxAutoStepsPerTurn}). ` +
152
+ `Break the cycle or increase maxAutoStepsPerTurn. Visited: ${visited.join(' → ')}.`
153
+ );
154
+ }
155
+
156
+ logger.debug(`[AutoChainExecutor] Processing auto-step: ${step.id} (${visited.length}/${maxAutoStepsPerTurn})`);
157
+
158
+ // STEP 1: skip evaluation (code-only predicates, OR semantics)
159
+ if (step.skip) {
160
+ const templateContext = createTemplateContext<TContext, TData>({
161
+ context,
162
+ data: session.data,
163
+ session,
164
+ history,
165
+ });
166
+ const skipResult = await step.evaluateSkip(templateContext);
167
+
168
+ if (skipResult.shouldSkip) {
169
+ logger.debug(`[AutoChainExecutor] Skipping auto-step ${step.id} due to skip condition`);
170
+ const nextSteps = step.getTransitions();
171
+ if (nextSteps.length === 0) {
172
+ // Last step was skipped and has no successor → flow complete
173
+ return { stoppedReason: 'last_step', session };
174
+ }
175
+ session = enterStep(session, nextSteps[0].id, nextSteps[0].description);
176
+ continue;
177
+ }
178
+ }
179
+
180
+ // STEP 2: requires assertion
181
+ if (step.requires && step.requires.length > 0) {
182
+ const sessionData = (session.data || {}) as Record<string, unknown>;
183
+ const missing = step.requires.filter(
184
+ field => sessionData[String(field)] === undefined
185
+ );
186
+ if (missing.length > 0) {
187
+ throw new FlowConfigurationError(
188
+ `[FlowConfigurationError] Auto-step "${step.id}" missing required fields: fields [${missing.join(', ')}] must be populated before this step runs. ` +
189
+ `Ensure a preceding step or hook populates these fields.`
190
+ );
191
+ }
192
+ }
193
+
194
+ // STEP 3: Run pre-LLM hooks (onEnter, prepare) and collect directives
195
+ const merged = await this.runStepHooks(step, session, context);
196
+
197
+ // Apply state writes immediately so subsequent steps see them
198
+ if (merged) {
199
+ if (merged.dataUpdate && Object.keys(merged.dataUpdate).length > 0) {
200
+ session = mergeCollected(session, merged.dataUpdate);
201
+ logger.debug(`[AutoChainExecutor] Applied dataUpdate from step ${step.id}`);
202
+ }
203
+ if (merged.contextUpdate && Object.keys(merged.contextUpdate).length > 0) {
204
+ // contextUpdate is reserved for future agent-level application.
205
+ // The caller can read mergedDirective.contextUpdate and apply it externally.
206
+ logger.debug(`[AutoChainExecutor] contextUpdate from step ${step.id} will be applied by caller`);
207
+ }
208
+
209
+ // STEP 4: halt short-circuit
210
+ if (merged.halt) {
211
+ logger.debug(`[AutoChainExecutor] Halt directive from step ${step.id}`);
212
+ return {
213
+ resolvedStep: step,
214
+ mergedDirective: merged,
215
+ stoppedReason: 'halt',
216
+ session,
217
+ };
218
+ }
219
+
220
+ // STEP 5: position-changing directive (goToStep, goTo, complete)
221
+ if (merged.goToStep) {
222
+ const targetStep = flow.getStep(merged.goToStep);
223
+ if (!targetStep) {
224
+ throw new FlowConfigurationError(
225
+ `[FlowConfigurationError] Auto-step "${step.id}" goToStep targets unknown step: "${merged.goToStep}" does not exist in the current flow. ` +
226
+ `Check the step id or use goTo to target a different flow.`
227
+ );
228
+ }
229
+ session = enterStep(session, targetStep.id, targetStep.description);
230
+ logger.debug(`[AutoChainExecutor] Position directive goToStep → ${targetStep.id}`);
231
+ continue; // Re-enter loop at the new step (which may itself be auto)
232
+ }
233
+ if (merged.goTo) {
234
+ // goTo targets a flow — return to pipeline for cross-flow handling
235
+ return {
236
+ resolvedStep: step,
237
+ mergedDirective: merged,
238
+ stoppedReason: 'goto',
239
+ session,
240
+ };
241
+ }
242
+ if (merged.complete) {
243
+ return {
244
+ resolvedStep: step,
245
+ mergedDirective: merged,
246
+ stoppedReason: 'completed',
247
+ session,
248
+ };
249
+ }
250
+ }
251
+
252
+ // STEP 6: branches resolution (if step has branches)
253
+ const stepWithBranches = step as unknown as StepWithBranches<TContext, TData>;
254
+ if (stepWithBranches.branches && Array.isArray(stepWithBranches.branches) && stepWithBranches.branches.length > 0) {
255
+ const branchTarget = await this.evaluateBranches(
256
+ stepWithBranches.branches,
257
+ session,
258
+ context,
259
+ history
260
+ );
261
+ if (branchTarget) {
262
+ // Check if it resolves to a step in this flow
263
+ const targetStep = flow.getStep(branchTarget);
264
+ if (targetStep) {
265
+ session = enterStep(session, targetStep.id, targetStep.description);
266
+ logger.debug(`[AutoChainExecutor] Branch resolved → ${targetStep.id}`);
267
+ continue;
268
+ }
269
+ // Not a step in this flow — treat as a flow id, return to pipeline
270
+ return {
271
+ resolvedStep: step,
272
+ mergedDirective: { goTo: branchTarget },
273
+ stoppedReason: 'goto',
274
+ session,
275
+ };
276
+ }
277
+ // No branch matched — fall through to linear advance
278
+ }
279
+
280
+ // STEP 7: linear advance
281
+ const nextSteps = step.getTransitions();
282
+ if (nextSteps.length === 0) {
283
+ // Auto-step is the last step → flow completes
284
+ logger.debug(`[AutoChainExecutor] Auto-step ${step.id} is terminal — flow complete`);
285
+ return { stoppedReason: 'last_step', session };
286
+ }
287
+
288
+ // Take the first transition (linear advance)
289
+ session = enterStep(session, nextSteps[0].id, nextSteps[0].description);
290
+ }
291
+ }
292
+
293
+ /**
294
+ * Run onEnter and prepare hooks for an auto-step, collecting any
295
+ * PreDirective-like return values.
296
+ */
297
+ private async runStepHooks(
298
+ step: Step<TContext, TData>,
299
+ session: SessionState<TData>,
300
+ context: TContext
301
+ ): Promise<AutoStepPrepareResult | undefined> {
302
+ let merged: AutoStepPrepareResult | undefined;
303
+
304
+ // onEnter (future hook — not yet in StepOptions, but handle if present)
305
+ const stepWithHooks = step as unknown as StepWithBranches<TContext, TData>;
306
+ if (typeof stepWithHooks.onEnter === 'function') {
307
+ const onEnterResult = await stepWithHooks.onEnter(context, session.data);
308
+ if (onEnterResult && typeof onEnterResult === 'object') {
309
+ merged = this.mergeDirectives(merged, onEnterResult as AutoStepPrepareResult);
310
+ }
311
+ }
312
+
313
+ // prepare hook — for auto-steps, prepare may return a PreDirective-like object
314
+ if (step.prepare) {
315
+ if (typeof step.prepare === 'function') {
316
+ const prepareResult = await (step.prepare as (
317
+ context: TContext,
318
+ data?: Partial<TData>
319
+ ) => Promise<unknown>)(
320
+ context,
321
+ session.data
322
+ );
323
+ // prepare may return void or a directive-like object
324
+ if (prepareResult && typeof prepareResult === 'object') {
325
+ merged = this.mergeDirectives(merged, prepareResult as AutoStepPrepareResult);
326
+ }
327
+ } else {
328
+ // Tool reference (string or Tool object) — for auto-steps, tool-based
329
+ // prepare cannot return directives. Log a warning.
330
+ logger.warn(
331
+ `[FlowConfigurationError] Auto-step "${step.id}" has a tool-based prepare: tool-based prepare on auto-steps cannot return directives. ` +
332
+ `Use a function-based prepare hook instead.`
333
+ );
334
+ }
335
+ }
336
+
337
+ return merged;
338
+ }
339
+
340
+ /**
341
+ * Merge two directive-like objects. Later values override earlier ones
342
+ * for scalar fields; object fields (dataUpdate, contextUpdate) are deep-merged.
343
+ */
344
+ private mergeDirectives(
345
+ base: AutoStepPrepareResult | undefined,
346
+ incoming: AutoStepPrepareResult
347
+ ): AutoStepPrepareResult {
348
+ if (!base) return { ...incoming };
349
+ return {
350
+ dataUpdate: incoming.dataUpdate
351
+ ? { ...(base.dataUpdate || {}), ...incoming.dataUpdate }
352
+ : base.dataUpdate,
353
+ contextUpdate: incoming.contextUpdate
354
+ ? { ...(base.contextUpdate || {}), ...incoming.contextUpdate }
355
+ : base.contextUpdate,
356
+ halt: incoming.halt ?? base.halt,
357
+ reply: incoming.reply ?? base.reply,
358
+ goTo: incoming.goTo ?? base.goTo,
359
+ goToStep: incoming.goToStep ?? base.goToStep,
360
+ complete: incoming.complete ?? base.complete,
361
+ };
362
+ }
363
+
364
+ /**
365
+ * Evaluate branches on an auto-step. Returns the target step/flow id
366
+ * if a branch matches, or undefined if no branch matched.
367
+ *
368
+ * This is a simplified evaluator for code-only (`if`) branches.
369
+ * AI-evaluated (`when`) branches are not supported in the auto-step
370
+ * context (no LLM call). If a branch entry has only `when`, it is skipped.
371
+ */
372
+ private async evaluateBranches(
373
+ branches: BranchEntry<TContext, TData>[],
374
+ session: SessionState<TData>,
375
+ context: TContext,
376
+ history: Event[]
377
+ ): Promise<string | undefined> {
378
+ for (let i = 0; i < branches.length; i++) {
379
+ const entry = branches[i];
380
+
381
+ // Unconditional entry (no `if` and no `when`) — must be last, always matches
382
+ if (!entry.if && !entry.when) {
383
+ return this.resolveBranchThen(entry.then);
384
+ }
385
+
386
+ // Code predicate evaluation
387
+ if (entry.if) {
388
+ const predicates = Array.isArray(entry.if) ? entry.if : [entry.if];
389
+ const predicateContext: BranchPredicateContext<TContext, TData> = { data: session.data, context, session, history };
390
+
391
+ let allPassed = true;
392
+ for (const predicate of predicates) {
393
+ if (typeof predicate === 'function') {
394
+ const result = await predicate(predicateContext);
395
+ if (!result) {
396
+ allPassed = false;
397
+ break;
398
+ }
399
+ }
400
+ }
401
+
402
+ if (!allPassed) continue;
403
+
404
+ // If entry also has `when`, skip it in auto-step context (no LLM available)
405
+ if (entry.when) {
406
+ logger.debug(
407
+ `[AutoChainExecutor] Branch entry has 'when' condition — ` +
408
+ `skipping AI evaluation in auto-step context`
409
+ );
410
+ continue;
411
+ }
412
+
413
+ return this.resolveBranchThen(entry.then);
414
+ }
415
+
416
+ // Entry has only `when` (AI condition) — skip in auto-step context
417
+ if (entry.when && !entry.if) {
418
+ continue;
419
+ }
420
+ }
421
+
422
+ return undefined;
423
+ }
424
+
425
+ /**
426
+ * Resolve a branch entry's `then` value to a string target.
427
+ * Handles both string targets and Directive objects.
428
+ */
429
+ private resolveBranchThen(then: BranchThen): string | undefined {
430
+ if (typeof then === 'string') {
431
+ return then;
432
+ }
433
+ // Directive object — extract position field
434
+ if (then && typeof then === 'object') {
435
+ if (then.goToStep) return then.goToStep;
436
+ if (then.goTo) return then.goTo;
437
+ }
438
+ return undefined;
439
+ }
440
+ }
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Branch Evaluator — Resolution Algorithm (Algorithm 2 from design.md)
3
+ *
4
+ * Pure function that evaluates a BranchMap in declaration order.
5
+ * Code-first evaluation: `if` predicates run before `when` (AI) conditions
6
+ * to save tokens. First matching entry wins.
7
+ *
8
+ * @module BranchEvaluator
9
+ */
10
+
11
+ import type {
12
+ BranchMap,
13
+ BranchPredicate,
14
+ BranchPredicateContext,
15
+ Directive,
16
+ } from "../types/flow";
17
+ import type { AiProvider } from "../types/ai";
18
+ import type { Event } from "../types/history";
19
+ import { eventsToHistory, logger } from "../utils";
20
+
21
+ /**
22
+ * The AI condition evaluator function signature.
23
+ * Accepts an array of condition strings (AND semantics) and returns
24
+ * whether all conditions are satisfied.
25
+ *
26
+ * This is the same evaluation mechanism used by `step.when` — condition
27
+ * strings are evaluated by the AI provider against the conversation context.
28
+ */
29
+ export type AiConditionEvaluator = (conditions: string[]) => Promise<boolean>;
30
+
31
+ /**
32
+ * Creates an `AiConditionEvaluator` bound to a provider and conversation context.
33
+ *
34
+ * Reuses the same evaluation pattern as `step.when` array forms: condition
35
+ * strings are passed to the AI provider for evaluation against the conversation
36
+ * history. No new prompt scaffolding — the provider evaluates whether the
37
+ * conditions are met based on the conversation so far.
38
+ *
39
+ * String form (`when: "some condition"`) is normalized to a single-element
40
+ * array by the caller (`evaluateBranches`) for uniformity before reaching
41
+ * this function.
42
+ *
43
+ * @param provider - The AI provider to use for condition evaluation
44
+ * @param history - Conversation history (events) for context
45
+ * @param context - Agent-level context
46
+ * @returns An `AiConditionEvaluator` function
47
+ */
48
+ export function createAiConditionEvaluator<TContext = unknown>(
49
+ provider: AiProvider,
50
+ history: Event[],
51
+ context: TContext,
52
+ ): AiConditionEvaluator {
53
+ return async (conditions: string[]): Promise<boolean> => {
54
+ if (conditions.length === 0) {
55
+ return true;
56
+ }
57
+
58
+ const conditionText = conditions.length === 1
59
+ ? conditions[0]
60
+ : conditions.map((c, i) => `${i + 1}. ${c}`).join("\n");
61
+
62
+ const prompt = [
63
+ "Evaluate whether the following condition(s) are met based on the conversation so far.",
64
+ "",
65
+ "Condition(s):",
66
+ conditionText,
67
+ "",
68
+ "Return JSON with a single boolean field `result`: true if ALL conditions are satisfied, false otherwise.",
69
+ ].join("\n");
70
+
71
+ const result = await provider.generateMessage<TContext, { result: boolean }>({
72
+ prompt,
73
+ history: eventsToHistory(history),
74
+ context,
75
+ parameters: {
76
+ jsonSchema: {
77
+ type: "object",
78
+ properties: {
79
+ result: {
80
+ type: "boolean",
81
+ description: "Whether all conditions are met based on the conversation context",
82
+ },
83
+ },
84
+ required: ["result"],
85
+ additionalProperties: false,
86
+ },
87
+ schemaName: "condition_evaluation",
88
+ },
89
+ });
90
+
91
+ return result.structured?.result ?? false;
92
+ };
93
+ }
94
+
95
+ /**
96
+ * Evaluates a BranchMap in declaration order, returning the first matching
97
+ * entry's `then` value, or `undefined` if no entry matches.
98
+ *
99
+ * Resolution rules per entry:
100
+ * 1. Unconditional (no `when`, no `if`) → return `then` immediately.
101
+ * 2. `if` first: normalize to array, await each predicate, short-circuit on first falsy.
102
+ * 3. `when` second: only if `if` passed (or absent); call evaluateAi with condition strings.
103
+ * 4. Both passed (or only one set and it passed) → return `then`.
104
+ *
105
+ * Errors in predicates or AI evaluation are caught, logged at ERROR, and
106
+ * cause `evaluateBranches` to return `undefined` (graceful degradation).
107
+ */
108
+ export async function evaluateBranches<TContext = unknown, TData = unknown>(
109
+ branches: BranchMap<TContext, TData>,
110
+ ctx: BranchPredicateContext<TContext, TData>,
111
+ evaluateAi: AiConditionEvaluator,
112
+ ): Promise<string | Directive<TContext, TData> | undefined> {
113
+ try {
114
+ for (let i = 0; i < branches.length; i++) {
115
+ const entry = branches[i];
116
+
117
+ // Unconditional fallback: entry has neither `when` nor `if`.
118
+ // Validation guarantees this is the LAST entry.
119
+ if (!entry.when && !entry.if) {
120
+ return entry.then;
121
+ }
122
+
123
+ // Code predicate first (free evaluation)
124
+ if (entry.if) {
125
+ const predicates: BranchPredicate<TContext, TData>[] = Array.isArray(entry.if)
126
+ ? entry.if
127
+ : [entry.if];
128
+
129
+ let ifPassed = true;
130
+ for (const predicate of predicates) {
131
+ const result = await predicate(ctx);
132
+ if (!result) {
133
+ ifPassed = false;
134
+ break;
135
+ }
136
+ }
137
+
138
+ if (!ifPassed) {
139
+ continue; // skip this entry; do NOT evaluate `when`
140
+ }
141
+ }
142
+
143
+ // AI condition (costs tokens — only reached if `if` passed or was absent)
144
+ if (entry.when) {
145
+ const conditions: string[] = Array.isArray(entry.when)
146
+ ? entry.when
147
+ : [entry.when];
148
+
149
+ const aiResult = await evaluateAi(conditions);
150
+ if (!aiResult) {
151
+ continue; // skip this entry
152
+ }
153
+ }
154
+
155
+ // Both passed (or only one was set and it passed)
156
+ return entry.then;
157
+ }
158
+
159
+ // No entry matched
160
+ return undefined;
161
+ } catch (error) {
162
+ logger.error(
163
+ `[BranchEvaluator] Error during branch evaluation: ${error instanceof Error ? error.message : String(error)}`
164
+ );
165
+ return undefined;
166
+ }
167
+ }