@falai/agent 1.2.7 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (508) hide show
  1. package/README.md +40 -886
  2. package/dist/adapters/MemoryAdapter.js +2 -2
  3. package/dist/adapters/MemoryAdapter.js.map +1 -1
  4. package/dist/adapters/MongoAdapter.js +2 -2
  5. package/dist/adapters/MongoAdapter.js.map +1 -1
  6. package/dist/adapters/OpenSearchAdapter.d.ts.map +1 -1
  7. package/dist/adapters/OpenSearchAdapter.js +9 -7
  8. package/dist/adapters/OpenSearchAdapter.js.map +1 -1
  9. package/dist/adapters/PostgreSQLAdapter.d.ts +14 -0
  10. package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  11. package/dist/adapters/PostgreSQLAdapter.js +25 -9
  12. package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
  13. package/dist/adapters/PrismaAdapter.js +5 -5
  14. package/dist/adapters/PrismaAdapter.js.map +1 -1
  15. package/dist/adapters/RedisAdapter.js +2 -2
  16. package/dist/adapters/RedisAdapter.js.map +1 -1
  17. package/dist/adapters/SQLiteAdapter.d.ts +17 -0
  18. package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
  19. package/dist/adapters/SQLiteAdapter.js +30 -11
  20. package/dist/adapters/SQLiteAdapter.js.map +1 -1
  21. package/dist/cjs/adapters/MemoryAdapter.js +2 -2
  22. package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
  23. package/dist/cjs/adapters/MongoAdapter.js +2 -2
  24. package/dist/cjs/adapters/MongoAdapter.js.map +1 -1
  25. package/dist/cjs/adapters/OpenSearchAdapter.d.ts.map +1 -1
  26. package/dist/cjs/adapters/OpenSearchAdapter.js +9 -7
  27. package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -1
  28. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts +14 -0
  29. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  30. package/dist/cjs/adapters/PostgreSQLAdapter.js +25 -9
  31. package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
  32. package/dist/cjs/adapters/PrismaAdapter.js +5 -5
  33. package/dist/cjs/adapters/PrismaAdapter.js.map +1 -1
  34. package/dist/cjs/adapters/RedisAdapter.js +2 -2
  35. package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
  36. package/dist/cjs/adapters/SQLiteAdapter.d.ts +17 -0
  37. package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
  38. package/dist/cjs/adapters/SQLiteAdapter.js +30 -11
  39. package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -1
  40. package/dist/cjs/constants/index.d.ts +0 -9
  41. package/dist/cjs/constants/index.d.ts.map +1 -1
  42. package/dist/cjs/constants/index.js +2 -11
  43. package/dist/cjs/constants/index.js.map +1 -1
  44. package/dist/cjs/core/Agent.d.ts +119 -153
  45. package/dist/cjs/core/Agent.d.ts.map +1 -1
  46. package/dist/cjs/core/Agent.js +471 -324
  47. package/dist/cjs/core/Agent.js.map +1 -1
  48. package/dist/cjs/core/AutoChainExecutor.d.ts +107 -0
  49. package/dist/cjs/core/AutoChainExecutor.d.ts.map +1 -0
  50. package/dist/cjs/core/AutoChainExecutor.js +297 -0
  51. package/dist/cjs/core/AutoChainExecutor.js.map +1 -0
  52. package/dist/cjs/core/BranchEvaluator.d.ts +54 -0
  53. package/dist/cjs/core/BranchEvaluator.d.ts.map +1 -0
  54. package/dist/cjs/core/BranchEvaluator.js +130 -0
  55. package/dist/cjs/core/BranchEvaluator.js.map +1 -0
  56. package/dist/cjs/core/DirectiveBus.d.ts +88 -0
  57. package/dist/cjs/core/DirectiveBus.d.ts.map +1 -0
  58. package/dist/cjs/core/DirectiveBus.js +196 -0
  59. package/dist/cjs/core/DirectiveBus.js.map +1 -0
  60. package/dist/cjs/core/DirectiveChainTracker.d.ts +49 -0
  61. package/dist/cjs/core/DirectiveChainTracker.d.ts.map +1 -0
  62. package/dist/cjs/core/DirectiveChainTracker.js +121 -0
  63. package/dist/cjs/core/DirectiveChainTracker.js.map +1 -0
  64. package/dist/cjs/core/Flow.d.ts +186 -0
  65. package/dist/cjs/core/Flow.d.ts.map +1 -0
  66. package/dist/cjs/core/Flow.js +550 -0
  67. package/dist/cjs/core/Flow.js.map +1 -0
  68. package/dist/cjs/core/FlowRouter.d.ts +182 -0
  69. package/dist/cjs/core/FlowRouter.d.ts.map +1 -0
  70. package/dist/cjs/core/{RoutingEngine.js → FlowRouter.js} +323 -306
  71. package/dist/cjs/core/FlowRouter.js.map +1 -0
  72. package/dist/cjs/core/PersistenceManager.d.ts +2 -2
  73. package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
  74. package/dist/cjs/core/PersistenceManager.js +7 -7
  75. package/dist/cjs/core/PersistenceManager.js.map +1 -1
  76. package/dist/cjs/core/PromptComposer.d.ts +21 -8
  77. package/dist/cjs/core/PromptComposer.d.ts.map +1 -1
  78. package/dist/cjs/core/PromptComposer.js +182 -105
  79. package/dist/cjs/core/PromptComposer.js.map +1 -1
  80. package/dist/cjs/core/PromptSectionCache.d.ts +1 -1
  81. package/dist/cjs/core/PromptSectionCache.js +1 -1
  82. package/dist/cjs/core/ResponseEngine.d.ts +18 -8
  83. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
  84. package/dist/cjs/core/ResponseEngine.js +38 -36
  85. package/dist/cjs/core/ResponseEngine.js.map +1 -1
  86. package/dist/cjs/core/ResponseModal.d.ts +73 -56
  87. package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
  88. package/dist/cjs/core/ResponseModal.js +1196 -1015
  89. package/dist/cjs/core/ResponseModal.js.map +1 -1
  90. package/dist/cjs/core/ResponsePipeline.d.ts +124 -26
  91. package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -1
  92. package/dist/cjs/core/ResponsePipeline.js +524 -134
  93. package/dist/cjs/core/ResponsePipeline.js.map +1 -1
  94. package/dist/cjs/core/SignalEvaluator.d.ts +86 -0
  95. package/dist/cjs/core/SignalEvaluator.d.ts.map +1 -0
  96. package/dist/cjs/core/SignalEvaluator.js +333 -0
  97. package/dist/cjs/core/SignalEvaluator.js.map +1 -0
  98. package/dist/cjs/core/SignalProcessor.d.ts +152 -0
  99. package/dist/cjs/core/SignalProcessor.d.ts.map +1 -0
  100. package/dist/cjs/core/SignalProcessor.js +562 -0
  101. package/dist/cjs/core/SignalProcessor.js.map +1 -0
  102. package/dist/cjs/core/Step.d.ts +43 -32
  103. package/dist/cjs/core/Step.d.ts.map +1 -1
  104. package/dist/cjs/core/Step.js +221 -126
  105. package/dist/cjs/core/Step.js.map +1 -1
  106. package/dist/cjs/core/StreamingToolExecutor.d.ts +2 -2
  107. package/dist/cjs/core/StreamingToolExecutor.d.ts.map +1 -1
  108. package/dist/cjs/core/StreamingToolExecutor.js.map +1 -1
  109. package/dist/cjs/core/ToolManager.d.ts +44 -13
  110. package/dist/cjs/core/ToolManager.d.ts.map +1 -1
  111. package/dist/cjs/core/ToolManager.js +174 -91
  112. package/dist/cjs/core/ToolManager.js.map +1 -1
  113. package/dist/cjs/core/createAgent.d.ts +35 -0
  114. package/dist/cjs/core/createAgent.d.ts.map +1 -0
  115. package/dist/cjs/core/createAgent.js +39 -0
  116. package/dist/cjs/core/createAgent.js.map +1 -0
  117. package/dist/cjs/core/flow-namespace.d.ts +49 -0
  118. package/dist/cjs/core/flow-namespace.d.ts.map +1 -0
  119. package/dist/cjs/core/flow-namespace.js +171 -0
  120. package/dist/cjs/core/flow-namespace.js.map +1 -0
  121. package/dist/cjs/index.d.ts +11 -14
  122. package/dist/cjs/index.d.ts.map +1 -1
  123. package/dist/cjs/index.js +18 -22
  124. package/dist/cjs/index.js.map +1 -1
  125. package/dist/cjs/providers/GeminiProvider.d.ts +3 -3
  126. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  127. package/dist/cjs/providers/GeminiProvider.js +16 -14
  128. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  129. package/dist/cjs/types/agent.d.ts +183 -54
  130. package/dist/cjs/types/agent.d.ts.map +1 -1
  131. package/dist/cjs/types/agent.js +0 -6
  132. package/dist/cjs/types/agent.js.map +1 -1
  133. package/dist/cjs/types/ai.d.ts +3 -3
  134. package/dist/cjs/types/ai.d.ts.map +1 -1
  135. package/dist/cjs/types/errors.d.ts +15 -0
  136. package/dist/cjs/types/errors.d.ts.map +1 -0
  137. package/dist/cjs/types/errors.js +22 -0
  138. package/dist/cjs/types/errors.js.map +1 -0
  139. package/dist/cjs/types/flow.d.ts +513 -0
  140. package/dist/cjs/types/flow.d.ts.map +1 -0
  141. package/dist/cjs/types/{route.js → flow.js} +2 -2
  142. package/dist/cjs/types/flow.js.map +1 -0
  143. package/dist/cjs/types/index.d.ts +7 -6
  144. package/dist/cjs/types/index.d.ts.map +1 -1
  145. package/dist/cjs/types/index.js +6 -2
  146. package/dist/cjs/types/index.js.map +1 -1
  147. package/dist/cjs/types/persistence.d.ts +11 -7
  148. package/dist/cjs/types/persistence.d.ts.map +1 -1
  149. package/dist/cjs/types/routing.d.ts +1 -1
  150. package/dist/cjs/types/routing.d.ts.map +1 -1
  151. package/dist/cjs/types/session.d.ts +24 -23
  152. package/dist/cjs/types/session.d.ts.map +1 -1
  153. package/dist/cjs/types/signals.d.ts +248 -0
  154. package/dist/cjs/types/signals.d.ts.map +1 -0
  155. package/dist/cjs/types/signals.js +11 -0
  156. package/dist/cjs/types/signals.js.map +1 -0
  157. package/dist/cjs/types/template.d.ts +2 -8
  158. package/dist/cjs/types/template.d.ts.map +1 -1
  159. package/dist/cjs/types/tool.d.ts +36 -29
  160. package/dist/cjs/types/tool.d.ts.map +1 -1
  161. package/dist/cjs/types/tool.js +1 -1
  162. package/dist/cjs/types/tool.js.map +1 -1
  163. package/dist/cjs/utils/condition.d.ts +7 -1
  164. package/dist/cjs/utils/condition.d.ts.map +1 -1
  165. package/dist/cjs/utils/condition.js.map +1 -1
  166. package/dist/cjs/utils/id.d.ts +13 -5
  167. package/dist/cjs/utils/id.d.ts.map +1 -1
  168. package/dist/cjs/utils/id.js +24 -10
  169. package/dist/cjs/utils/id.js.map +1 -1
  170. package/dist/cjs/utils/index.d.ts +2 -2
  171. package/dist/cjs/utils/index.d.ts.map +1 -1
  172. package/dist/cjs/utils/index.js +7 -3
  173. package/dist/cjs/utils/index.js.map +1 -1
  174. package/dist/cjs/utils/session.d.ts +44 -5
  175. package/dist/cjs/utils/session.d.ts.map +1 -1
  176. package/dist/cjs/utils/session.js +197 -38
  177. package/dist/cjs/utils/session.js.map +1 -1
  178. package/dist/constants/index.d.ts +0 -9
  179. package/dist/constants/index.d.ts.map +1 -1
  180. package/dist/constants/index.js +3 -9
  181. package/dist/constants/index.js.map +1 -1
  182. package/dist/core/Agent.d.ts +119 -153
  183. package/dist/core/Agent.d.ts.map +1 -1
  184. package/dist/core/Agent.js +472 -325
  185. package/dist/core/Agent.js.map +1 -1
  186. package/dist/core/AutoChainExecutor.d.ts +107 -0
  187. package/dist/core/AutoChainExecutor.d.ts.map +1 -0
  188. package/dist/core/AutoChainExecutor.js +293 -0
  189. package/dist/core/AutoChainExecutor.js.map +1 -0
  190. package/dist/core/BranchEvaluator.d.ts +54 -0
  191. package/dist/core/BranchEvaluator.d.ts.map +1 -0
  192. package/dist/core/BranchEvaluator.js +126 -0
  193. package/dist/core/BranchEvaluator.js.map +1 -0
  194. package/dist/core/DirectiveBus.d.ts +88 -0
  195. package/dist/core/DirectiveBus.d.ts.map +1 -0
  196. package/dist/core/DirectiveBus.js +192 -0
  197. package/dist/core/DirectiveBus.js.map +1 -0
  198. package/dist/core/DirectiveChainTracker.d.ts +49 -0
  199. package/dist/core/DirectiveChainTracker.d.ts.map +1 -0
  200. package/dist/core/DirectiveChainTracker.js +117 -0
  201. package/dist/core/DirectiveChainTracker.js.map +1 -0
  202. package/dist/core/Flow.d.ts +186 -0
  203. package/dist/core/Flow.d.ts.map +1 -0
  204. package/dist/core/Flow.js +546 -0
  205. package/dist/core/Flow.js.map +1 -0
  206. package/dist/core/FlowRouter.d.ts +182 -0
  207. package/dist/core/FlowRouter.d.ts.map +1 -0
  208. package/dist/core/{RoutingEngine.js → FlowRouter.js} +322 -305
  209. package/dist/core/FlowRouter.js.map +1 -0
  210. package/dist/core/PersistenceManager.d.ts +2 -2
  211. package/dist/core/PersistenceManager.d.ts.map +1 -1
  212. package/dist/core/PersistenceManager.js +7 -7
  213. package/dist/core/PersistenceManager.js.map +1 -1
  214. package/dist/core/PromptComposer.d.ts +21 -8
  215. package/dist/core/PromptComposer.d.ts.map +1 -1
  216. package/dist/core/PromptComposer.js +183 -106
  217. package/dist/core/PromptComposer.js.map +1 -1
  218. package/dist/core/PromptSectionCache.d.ts +1 -1
  219. package/dist/core/PromptSectionCache.js +1 -1
  220. package/dist/core/ResponseEngine.d.ts +18 -8
  221. package/dist/core/ResponseEngine.d.ts.map +1 -1
  222. package/dist/core/ResponseEngine.js +38 -36
  223. package/dist/core/ResponseEngine.js.map +1 -1
  224. package/dist/core/ResponseModal.d.ts +73 -56
  225. package/dist/core/ResponseModal.d.ts.map +1 -1
  226. package/dist/core/ResponseModal.js +1198 -1017
  227. package/dist/core/ResponseModal.js.map +1 -1
  228. package/dist/core/ResponsePipeline.d.ts +124 -26
  229. package/dist/core/ResponsePipeline.d.ts.map +1 -1
  230. package/dist/core/ResponsePipeline.js +524 -135
  231. package/dist/core/ResponsePipeline.js.map +1 -1
  232. package/dist/core/SignalEvaluator.d.ts +86 -0
  233. package/dist/core/SignalEvaluator.d.ts.map +1 -0
  234. package/dist/core/SignalEvaluator.js +326 -0
  235. package/dist/core/SignalEvaluator.js.map +1 -0
  236. package/dist/core/SignalProcessor.d.ts +152 -0
  237. package/dist/core/SignalProcessor.d.ts.map +1 -0
  238. package/dist/core/SignalProcessor.js +555 -0
  239. package/dist/core/SignalProcessor.js.map +1 -0
  240. package/dist/core/Step.d.ts +43 -32
  241. package/dist/core/Step.d.ts.map +1 -1
  242. package/dist/core/Step.js +220 -126
  243. package/dist/core/Step.js.map +1 -1
  244. package/dist/core/StreamingToolExecutor.d.ts +2 -2
  245. package/dist/core/StreamingToolExecutor.d.ts.map +1 -1
  246. package/dist/core/StreamingToolExecutor.js.map +1 -1
  247. package/dist/core/ToolManager.d.ts +44 -13
  248. package/dist/core/ToolManager.d.ts.map +1 -1
  249. package/dist/core/ToolManager.js +174 -91
  250. package/dist/core/ToolManager.js.map +1 -1
  251. package/dist/core/createAgent.d.ts +35 -0
  252. package/dist/core/createAgent.d.ts.map +1 -0
  253. package/dist/core/createAgent.js +36 -0
  254. package/dist/core/createAgent.js.map +1 -0
  255. package/dist/core/flow-namespace.d.ts +49 -0
  256. package/dist/core/flow-namespace.d.ts.map +1 -0
  257. package/dist/core/flow-namespace.js +168 -0
  258. package/dist/core/flow-namespace.js.map +1 -0
  259. package/dist/index.d.ts +11 -14
  260. package/dist/index.d.ts.map +1 -1
  261. package/dist/index.js +9 -12
  262. package/dist/index.js.map +1 -1
  263. package/dist/providers/GeminiProvider.d.ts +3 -3
  264. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  265. package/dist/providers/GeminiProvider.js +16 -14
  266. package/dist/providers/GeminiProvider.js.map +1 -1
  267. package/dist/types/agent.d.ts +183 -54
  268. package/dist/types/agent.d.ts.map +1 -1
  269. package/dist/types/agent.js +0 -6
  270. package/dist/types/agent.js.map +1 -1
  271. package/dist/types/ai.d.ts +3 -3
  272. package/dist/types/ai.d.ts.map +1 -1
  273. package/dist/types/errors.d.ts +15 -0
  274. package/dist/types/errors.d.ts.map +1 -0
  275. package/dist/types/errors.js +18 -0
  276. package/dist/types/errors.js.map +1 -0
  277. package/dist/types/flow.d.ts +513 -0
  278. package/dist/types/flow.d.ts.map +1 -0
  279. package/dist/types/flow.js +5 -0
  280. package/dist/types/flow.js.map +1 -0
  281. package/dist/types/index.d.ts +7 -6
  282. package/dist/types/index.d.ts.map +1 -1
  283. package/dist/types/index.js +4 -1
  284. package/dist/types/index.js.map +1 -1
  285. package/dist/types/persistence.d.ts +11 -7
  286. package/dist/types/persistence.d.ts.map +1 -1
  287. package/dist/types/routing.d.ts +1 -1
  288. package/dist/types/routing.d.ts.map +1 -1
  289. package/dist/types/session.d.ts +24 -23
  290. package/dist/types/session.d.ts.map +1 -1
  291. package/dist/types/signals.d.ts +248 -0
  292. package/dist/types/signals.d.ts.map +1 -0
  293. package/dist/types/signals.js +10 -0
  294. package/dist/types/signals.js.map +1 -0
  295. package/dist/types/template.d.ts +2 -8
  296. package/dist/types/template.d.ts.map +1 -1
  297. package/dist/types/tool.d.ts +36 -29
  298. package/dist/types/tool.d.ts.map +1 -1
  299. package/dist/types/tool.js +1 -1
  300. package/dist/types/tool.js.map +1 -1
  301. package/dist/utils/condition.d.ts +7 -1
  302. package/dist/utils/condition.d.ts.map +1 -1
  303. package/dist/utils/condition.js.map +1 -1
  304. package/dist/utils/id.d.ts +13 -5
  305. package/dist/utils/id.d.ts.map +1 -1
  306. package/dist/utils/id.js +22 -9
  307. package/dist/utils/id.js.map +1 -1
  308. package/dist/utils/index.d.ts +2 -2
  309. package/dist/utils/index.d.ts.map +1 -1
  310. package/dist/utils/index.js +2 -2
  311. package/dist/utils/index.js.map +1 -1
  312. package/dist/utils/session.d.ts +44 -5
  313. package/dist/utils/session.d.ts.map +1 -1
  314. package/dist/utils/session.js +193 -37
  315. package/dist/utils/session.js.map +1 -1
  316. package/docs/README.md +15 -202
  317. package/docs/concepts/architecture.md +281 -0
  318. package/docs/concepts/directives.md +400 -0
  319. package/docs/concepts/pipeline.md +399 -0
  320. package/docs/guides/branching.md +263 -0
  321. package/docs/guides/compaction.md +163 -0
  322. package/docs/guides/conditions.md +167 -0
  323. package/docs/guides/error-handling.md +176 -0
  324. package/docs/guides/flow-control.md +409 -0
  325. package/docs/guides/instructions.md +210 -0
  326. package/docs/guides/persistence.md +182 -0
  327. package/docs/guides/streaming.md +137 -0
  328. package/docs/migration/README.md +15 -0
  329. package/docs/migration/route-to-flow.md +560 -0
  330. package/docs/migration/v1-to-v2.md +909 -0
  331. package/docs/reference/adapters.md +481 -0
  332. package/docs/reference/branches.md +241 -0
  333. package/docs/reference/create-agent.md +186 -0
  334. package/docs/reference/directive.md +243 -0
  335. package/docs/reference/errors.md +122 -0
  336. package/docs/reference/flow.md +238 -0
  337. package/docs/reference/instruction.md +177 -0
  338. package/docs/reference/pre-directive.md +131 -0
  339. package/docs/reference/providers.md +227 -0
  340. package/docs/reference/signals.md +356 -0
  341. package/docs/reference/step.md +339 -0
  342. package/docs/reference/tool.md +269 -0
  343. package/docs/start/01-install.md +81 -0
  344. package/docs/start/02-first-agent.md +196 -0
  345. package/docs/start/03-collect-data.md +222 -0
  346. package/docs/start/04-add-tools.md +276 -0
  347. package/docs/start/05-go-to-production.md +216 -0
  348. package/examples/01-quickstart.ts +20 -0
  349. package/examples/02-data-extraction.ts +90 -0
  350. package/examples/03-tools.ts +136 -0
  351. package/examples/04-instructions.ts +100 -0
  352. package/examples/05-branching.ts +140 -0
  353. package/examples/06-flow-control.ts +103 -0
  354. package/examples/07-streaming.ts +69 -0
  355. package/examples/08-persistence.ts +98 -0
  356. package/examples/09-signals.ts +144 -0
  357. package/examples/tsconfig.json +30 -0
  358. package/package.json +2 -1
  359. package/src/adapters/MemoryAdapter.ts +3 -3
  360. package/src/adapters/MongoAdapter.ts +3 -3
  361. package/src/adapters/OpenSearchAdapter.ts +10 -8
  362. package/src/adapters/PostgreSQLAdapter.ts +26 -10
  363. package/src/adapters/PrismaAdapter.ts +6 -6
  364. package/src/adapters/RedisAdapter.ts +3 -3
  365. package/src/adapters/SQLiteAdapter.ts +31 -12
  366. package/src/constants/index.ts +2 -10
  367. package/src/core/Agent.ts +585 -374
  368. package/src/core/AutoChainExecutor.ts +440 -0
  369. package/src/core/BranchEvaluator.ts +167 -0
  370. package/src/core/DirectiveBus.ts +248 -0
  371. package/src/core/DirectiveChainTracker.ts +144 -0
  372. package/src/core/Flow.ts +666 -0
  373. package/src/core/{RoutingEngine.ts → FlowRouter.ts} +385 -365
  374. package/src/core/PersistenceManager.ts +8 -8
  375. package/src/core/PromptComposer.ts +209 -140
  376. package/src/core/PromptSectionCache.ts +1 -1
  377. package/src/core/ResponseEngine.ts +61 -46
  378. package/src/core/ResponseModal.ts +1458 -1241
  379. package/src/core/ResponsePipeline.ts +675 -173
  380. package/src/core/SignalEvaluator.ts +420 -0
  381. package/src/core/SignalProcessor.ts +723 -0
  382. package/src/core/Step.ts +279 -176
  383. package/src/core/StreamingToolExecutor.ts +4 -4
  384. package/src/core/ToolManager.ts +200 -97
  385. package/src/core/createAgent.ts +40 -0
  386. package/src/core/flow-namespace.ts +219 -0
  387. package/src/index.ts +42 -36
  388. package/src/providers/GeminiProvider.ts +17 -15
  389. package/src/types/agent.ts +182 -53
  390. package/src/types/ai.ts +3 -3
  391. package/src/types/errors.ts +18 -0
  392. package/src/types/flow.ts +590 -0
  393. package/src/types/index.ts +43 -16
  394. package/src/types/persistence.ts +12 -8
  395. package/src/types/routing.ts +1 -1
  396. package/src/types/session.ts +26 -23
  397. package/src/types/signals.ts +321 -0
  398. package/src/types/template.ts +3 -11
  399. package/src/types/tool.ts +50 -42
  400. package/src/utils/condition.ts +13 -4
  401. package/src/utils/id.ts +27 -9
  402. package/src/utils/index.ts +6 -2
  403. package/src/utils/session.ts +238 -42
  404. package/dist/cjs/core/BatchExecutor.d.ts +0 -359
  405. package/dist/cjs/core/BatchExecutor.d.ts.map +0 -1
  406. package/dist/cjs/core/BatchExecutor.js +0 -861
  407. package/dist/cjs/core/BatchExecutor.js.map +0 -1
  408. package/dist/cjs/core/BatchPromptBuilder.d.ts +0 -89
  409. package/dist/cjs/core/BatchPromptBuilder.d.ts.map +0 -1
  410. package/dist/cjs/core/BatchPromptBuilder.js +0 -223
  411. package/dist/cjs/core/BatchPromptBuilder.js.map +0 -1
  412. package/dist/cjs/core/Route.d.ts +0 -180
  413. package/dist/cjs/core/Route.d.ts.map +0 -1
  414. package/dist/cjs/core/Route.js +0 -542
  415. package/dist/cjs/core/Route.js.map +0 -1
  416. package/dist/cjs/core/RoutingEngine.d.ts +0 -185
  417. package/dist/cjs/core/RoutingEngine.d.ts.map +0 -1
  418. package/dist/cjs/core/RoutingEngine.js.map +0 -1
  419. package/dist/cjs/types/route.d.ts +0 -336
  420. package/dist/cjs/types/route.d.ts.map +0 -1
  421. package/dist/cjs/types/route.js.map +0 -1
  422. package/dist/core/BatchExecutor.d.ts +0 -359
  423. package/dist/core/BatchExecutor.d.ts.map +0 -1
  424. package/dist/core/BatchExecutor.js +0 -856
  425. package/dist/core/BatchExecutor.js.map +0 -1
  426. package/dist/core/BatchPromptBuilder.d.ts +0 -89
  427. package/dist/core/BatchPromptBuilder.d.ts.map +0 -1
  428. package/dist/core/BatchPromptBuilder.js +0 -219
  429. package/dist/core/BatchPromptBuilder.js.map +0 -1
  430. package/dist/core/Route.d.ts +0 -180
  431. package/dist/core/Route.d.ts.map +0 -1
  432. package/dist/core/Route.js +0 -538
  433. package/dist/core/Route.js.map +0 -1
  434. package/dist/core/RoutingEngine.d.ts +0 -185
  435. package/dist/core/RoutingEngine.d.ts.map +0 -1
  436. package/dist/core/RoutingEngine.js.map +0 -1
  437. package/dist/types/route.d.ts +0 -336
  438. package/dist/types/route.d.ts.map +0 -1
  439. package/dist/types/route.js +0 -5
  440. package/dist/types/route.js.map +0 -1
  441. package/docs/CONTRIBUTING.md +0 -521
  442. package/docs/api/README.md +0 -3299
  443. package/docs/api/overview.md +0 -1410
  444. package/docs/architecture/data-extraction-flow.md +0 -360
  445. package/docs/architecture/multi-step-execution.md +0 -277
  446. package/docs/core/agent/README.md +0 -938
  447. package/docs/core/agent/context-management.md +0 -796
  448. package/docs/core/agent/rules-and-prohibitions.md +0 -113
  449. package/docs/core/agent/session-management.md +0 -693
  450. package/docs/core/ai-integration/prompt-composition.md +0 -355
  451. package/docs/core/ai-integration/providers.md +0 -515
  452. package/docs/core/ai-integration/response-processing.md +0 -433
  453. package/docs/core/conversation-flows/data-collection.md +0 -772
  454. package/docs/core/conversation-flows/route-dsl.md +0 -509
  455. package/docs/core/conversation-flows/routes.md +0 -249
  456. package/docs/core/conversation-flows/step-transitions.md +0 -731
  457. package/docs/core/conversation-flows/steps.md +0 -268
  458. package/docs/core/error-handling.md +0 -830
  459. package/docs/core/persistence/adapters.md +0 -255
  460. package/docs/core/persistence/session-storage.md +0 -656
  461. package/docs/core/routing/intelligent-routing.md +0 -470
  462. package/docs/core/tools/enhanced-tool.md +0 -186
  463. package/docs/core/tools/streaming-execution.md +0 -161
  464. package/docs/core/tools/tool-definition.md +0 -970
  465. package/docs/core/tools/tool-scoping.md +0 -819
  466. package/docs/guides/advanced-patterns/publishing.md +0 -186
  467. package/docs/guides/context-compaction.md +0 -96
  468. package/docs/guides/error-handling-patterns.md +0 -578
  469. package/docs/guides/getting-started/README.md +0 -795
  470. package/docs/guides/migration/README.md +0 -101
  471. package/docs/guides/migration/flexible-routing-conditions.md +0 -375
  472. package/docs/guides/migration/multi-step-execution.md +0 -393
  473. package/docs/guides/migration/response-modal-refactor.md +0 -518
  474. package/docs/guides/prompt-optimization.md +0 -164
  475. package/examples/advanced-patterns/context-compaction.ts +0 -223
  476. package/examples/advanced-patterns/knowledge-based-agent.ts +0 -735
  477. package/examples/advanced-patterns/persistent-onboarding.ts +0 -728
  478. package/examples/advanced-patterns/route-lifecycle-hooks.ts +0 -556
  479. package/examples/advanced-patterns/streaming-responses.ts +0 -656
  480. package/examples/ai-providers/anthropic-integration.ts +0 -388
  481. package/examples/ai-providers/openai-integration.ts +0 -228
  482. package/examples/condition-patterns/function-only-conditions.ts +0 -365
  483. package/examples/condition-patterns/mixed-array-conditions.ts +0 -477
  484. package/examples/condition-patterns/route-skipif-patterns.ts +0 -468
  485. package/examples/condition-patterns/step-skipif-patterns.ts +0 -0
  486. package/examples/condition-patterns/string-only-conditions.ts +0 -296
  487. package/examples/conversation-flows/completion-transitions.ts +0 -318
  488. package/examples/core-concepts/basic-agent.ts +0 -503
  489. package/examples/core-concepts/modern-streaming-api.ts +0 -309
  490. package/examples/core-concepts/schema-driven-extraction.ts +0 -332
  491. package/examples/core-concepts/session-management.ts +0 -494
  492. package/examples/integrations/database-integration.ts +0 -631
  493. package/examples/integrations/healthcare-integration.ts +0 -595
  494. package/examples/integrations/search-integration.ts +0 -530
  495. package/examples/integrations/server-session-management.ts +0 -307
  496. package/examples/persistence/custom-adapter.ts +0 -526
  497. package/examples/persistence/database-persistence.ts +0 -583
  498. package/examples/persistence/memory-sessions.ts +0 -495
  499. package/examples/persistence/prisma-schema.example.prisma +0 -74
  500. package/examples/persistence/redis-persistence.ts +0 -488
  501. package/examples/tools/basic-tools.ts +0 -765
  502. package/examples/tools/data-enrichment-tools.ts +0 -593
  503. package/examples/tools/enhanced-tool-metadata.ts +0 -268
  504. package/examples/tools/streaming-tool-execution.ts +0 -283
  505. package/src/core/BatchExecutor.ts +0 -1187
  506. package/src/core/BatchPromptBuilder.ts +0 -299
  507. package/src/core/Route.ts +0 -678
  508. package/src/types/route.ts +0 -392
@@ -0,0 +1,339 @@
1
+ ---
2
+ title: "Step"
3
+ description: "A node inside a flow — collects data, calls tools, runs computational work, or speaks a verbatim line."
4
+ type: reference
5
+ order: 3
6
+ ---
7
+
8
+ # Step
9
+
10
+ > **Where this is introduced:** [Architecture](../concepts/architecture.md)
11
+
12
+ A `Step` is a single node inside a `Flow`. Each step describes what
13
+ the agent does at one point in a conversation: ask a question, collect
14
+ schema fields, call tools, run a hook, branch to another step, or
15
+ speak a verbatim line. Steps are the smallest unit the engine can
16
+ suspend on between user turns.
17
+
18
+ Steps are normally declared as `StepOptions` objects inside a flow's
19
+ `steps[]` array. The `Step` class itself is rarely instantiated by
20
+ hand — `createAgent` and `Flow.addStep` build instances from the
21
+ options shape below. Validation runs eagerly at construction, so
22
+ misuse surfaces as `FlowConfigurationError` before any turn runs.
23
+
24
+ A step is one of three mutually exclusive shapes:
25
+
26
+ - **LLM step** — the default. Has `prompt`, optionally `collect` / `tools` / `instructions`. The engine calls the LLM.
27
+ - **Auto step** — `auto: true`. Pure computation, no LLM call. Only `onEnter`, `prepare`, and `branches` execute. Counts against `maxAutoStepsPerTurn`.
28
+ - **Reply step** — `reply` is set. Renders a verbatim assistant message with no LLM call.
29
+
30
+ Mixing fields between shapes throws at construction time.
31
+
32
+ ## Signature
33
+
34
+ ```typescript
35
+ interface StepOptions<TContext = unknown, TData = unknown> {
36
+ id?: string;
37
+ description?: string;
38
+
39
+ // Behaviour
40
+ prompt?: Template<TContext, TData>;
41
+ reply?: Template<TContext, TData>;
42
+ auto?: boolean;
43
+
44
+ // Data
45
+ collect?: (keyof TData)[];
46
+ requires?: (keyof TData)[];
47
+
48
+ // Activation
49
+ when?: ConditionWhen; // AI strings — `string | string[]`
50
+ if?: ConditionIf<TContext, TData>; // code predicates — function or array
51
+ skip?: ConditionIf<TContext, TData>; // code predicates — OR semantics
52
+
53
+ // Surface
54
+ tools?: (string | Tool<TContext, TData>)[];
55
+ instructions?: Instruction<TContext, TData>[];
56
+
57
+ // Lifecycle (shorthand — returns PrepareResult)
58
+ prepare?:
59
+ | string // tool id
60
+ | Tool<TContext, TData>
61
+ | ((ctx: TContext, data?: Partial<TData>) =>
62
+ void | PrepareResult | Promise<void | PrepareResult>);
63
+ finalize?:
64
+ | string
65
+ | Tool<TContext, TData>
66
+ | ((ctx: TContext, data?: Partial<TData>) =>
67
+ void | PrepareResult | Promise<void | PrepareResult>);
68
+
69
+ // Lifecycle (full — receives HookContext, returns PreDirective / Directive)
70
+ hooks?: StepLifecycleHooks<TContext, TData>;
71
+
72
+ // Routing
73
+ branches?: BranchMap<TContext, TData>;
74
+ }
75
+
76
+ interface StepLifecycleHooks<TContext = unknown, TData = unknown> {
77
+ onEnter?: (ctx: HookContext<TContext, TData>) =>
78
+ void | PreDirective<TContext, TData> | Promise<void | PreDirective<TContext, TData>>;
79
+ prepare?: (ctx: HookContext<TContext, TData>) =>
80
+ void | PreDirective<TContext, TData> | Promise<void | PreDirective<TContext, TData>>;
81
+ finalize?: (ctx: HookContext<TContext, TData>) =>
82
+ void | Directive<TContext, TData> | Promise<void | Directive<TContext, TData>>;
83
+ onExit?: (ctx: HookContext<TContext, TData>, reason: ExitReason) =>
84
+ void | Promise<void>;
85
+ }
86
+ ```
87
+
88
+ ## Fields
89
+
90
+ | Field | Type | Required | Default | Notes |
91
+ |-------|------|----------|---------|-------|
92
+ | `id` | `string` | no | derived from `description` | Stable identifier used by `goToStep`, `branches.then`, and event traces. Must be unique within the flow. |
93
+ | `description` | `string` | no | — | One-line summary surfaced in routing and event traces. Used to derive `id` when omitted. |
94
+ | `prompt` | `Template<TContext, TData>` | no | — | String or function `(params) => string \| Promise<string>`. Becomes the system-prompt instruction for the LLM call this step makes. Mutually exclusive with `auto: true` and `reply`. |
95
+ | `reply` | `Template<TContext, TData>` | no | — | Verbatim assistant message. When set, the engine renders this template and emits it without calling the LLM. Cannot coexist with `prompt`, `collect`, `tools`, `finalize`, or `auto: true`. `stoppedReason: 'reply'`. |
96
+ | `auto` | `boolean` | no | `false` | When `true`, the step runs without an LLM call — only `onEnter`, `prepare`, and `branches` execute. Cannot coexist with `prompt`, `collect`, `tools`, or `finalize`. Counts against `maxAutoStepsPerTurn`. |
97
+ | `collect` | `(keyof TData)[]` | no | `[]` | Schema field keys this step is responsible for extracting from the user message. Every key must exist in the agent's `schema`. The engine skips the step automatically when every listed key is already present in `session.data` (pre-extraction). |
98
+ | `requires` | `(keyof TData)[]` | no | `[]` | Prerequisite field keys. The engine refuses to enter the step until every key is present in `session.data`. When fields covered by `requires` are read inside `branches[].if` predicates, they are guaranteed to be defined. |
99
+ | `when` | `string \| string[]` | no | — | AI-evaluated activation strings (AND semantics). Evaluated by the LLM at routing time. Functions are not allowed here — the constructor throws `FlowConfigurationError` if a function is found. |
100
+ | `if` | `(ctx) => boolean \| Promise<boolean>` or array | no | — | Code-evaluated activation predicates (AND semantics). Evaluated locally — no LLM cost. When both `when` and `if` are set, `if` runs first; `when` is only evaluated if every `if` predicate passes. |
101
+ | `skip` | `(ctx) => boolean \| Promise<boolean>` or array | no | — | Code-evaluated skip predicates (OR semantics). When any predicate returns `true`, the step is bypassed. Only code predicates — no AI strings. |
102
+ | `tools` | `(string \| Tool<TContext, TData>)[]` | no | `[]` | Tools available during this step. Strings are resolved against the agent's tool registry; objects are inline tools. Stacked on top of agent and flow scopes. |
103
+ | `instructions` | `Instruction<TContext, TData>[]` | no | `[]` | Step-scoped behavioural statements (`kind: 'must' \| 'never' \| 'should'`). Active only while this step is current. See [Instruction](./instruction.md). |
104
+ | `prepare` | function, tool id, or `Tool` object | no | — | **Shorthand** pre-LLM hook. Receives `(context, data?)` and returns `void \| PrepareResult`. For full directive control, use `hooks.prepare` instead. |
105
+ | `finalize` | function, tool id, or `Tool` object | no | — | **Shorthand** post-LLM hook. Same shape as `prepare`. For full directive control, use `hooks.finalize` instead. |
106
+ | `hooks` | `StepLifecycleHooks<TContext, TData>` | no | — | Full lifecycle callbacks: `onEnter`, `prepare`, `finalize`, `onExit`. See the table below. |
107
+ | `branches` | `BranchEntry<TContext, TData>[]` | no | — | Explicit source-local fork. Evaluated after `finalize`, before linear successor selection. The first entry whose `if`/`when` passes wins; its `then` resolves to a step id, a flow id, or a `Directive`. See [Branches](./branches.md). |
108
+
109
+ ### Lifecycle hooks
110
+
111
+ The lifecycle has four positions. Two of them — `prepare` and
112
+ `finalize` — are also reachable through the top-level shorthand
113
+ fields, with a smaller return type.
114
+
115
+ | Hook | When it fires | `hooks.<name>` returns | Top-level shorthand returns | Use it for |
116
+ |------|---------------|------------------------|------------------------------|------------|
117
+ | `onEnter` | Before any other work the first time the step becomes current. | `void \| PreDirective` | n/a (no shorthand) | Append per-turn prompt context, inject one-turn tools, or short-circuit with `halt + reply`. |
118
+ | `prepare` | Right before the LLM call, after `onEnter`. | `void \| PreDirective` | `void \| PrepareResult` | Mutate session data, fetch external context, halt the LLM call. |
119
+ | `finalize` | After the LLM call and tool loop complete. | `void \| Directive` | `void \| PrepareResult` | Validate collected data, redirect with `goTo` / `goToStep`, complete the flow. |
120
+ | `onExit` | When the step is left (next step entered, flow completed, aborted). | `void` | n/a | Emit telemetry. Cannot influence flow control. |
121
+
122
+ `PrepareResult` is the shorthand return — a flat object with the
123
+ common Directive fields (`dataUpdate`, `contextUpdate`, `goTo`,
124
+ `goToStep`, `complete`, `halt`, `reply`). Use `hooks.<name>` when you
125
+ need the full `HookContext` (with `session`, `history`, `dispatch`)
126
+ or the full `Directive` / `PreDirective` surface (`appendPrompt`,
127
+ `injectTools`, `abort`, `reset`).
128
+
129
+ ### Resolution within a step
130
+
131
+ For one step, the engine walks this sequence per turn:
132
+
133
+ 1. Evaluate `if` (code, AND) and `when` (AI, AND) — fails skip the step entirely.
134
+ 2. Evaluate `skip` (code, OR) — true means bypass and fall through.
135
+ 3. Check `requires` — refuse entry if any required field is missing.
136
+ 4. Run `onEnter`, then `prepare` / `hooks.prepare`. May emit a `PreDirective`.
137
+ 5. **LLM step**: call the LLM with the step's prompt, tools, and instructions; tool loop runs until completion. **Auto step**: skip the LLM call. **Reply step**: render `reply` as the verbatim assistant message.
138
+ 6. Run `finalize` / `hooks.finalize`. May emit a `Directive`.
139
+ 7. Evaluate `branches`. The first entry whose `if`/`when` passes wins; its `then` resolves to a step id, a flow id, or a full `Directive`. If no entry matches, fall through.
140
+ 8. Linear successor / AI step selection.
141
+ 9. Run `onExit` for the step we are leaving.
142
+
143
+ ## Examples
144
+
145
+ ### Collecting fields with prerequisites and skip
146
+
147
+ ```typescript
148
+ import { createAgent, GeminiProvider } from '@falai/agent';
149
+
150
+ const agent = createAgent({
151
+ name: 'BookingBot',
152
+ provider: new GeminiProvider({ apiKey: process.env.GEMINI_API_KEY! }),
153
+ schema: {
154
+ type: 'object',
155
+ properties: {
156
+ city: { type: 'string' },
157
+ checkIn: { type: 'string' },
158
+ guests: { type: 'integer' },
159
+ },
160
+ },
161
+ flows: [
162
+ {
163
+ title: 'Book',
164
+ requiredFields: ['city', 'checkIn', 'guests'],
165
+ steps: [
166
+ {
167
+ id: 'ask_destination',
168
+ prompt: 'Find out where and when the user wants to stay.',
169
+ collect: ['city', 'checkIn'],
170
+ },
171
+ {
172
+ id: 'ask_guests',
173
+ prompt: 'Confirm how many people are travelling.',
174
+ collect: ['guests'],
175
+ requires: ['city', 'checkIn'],
176
+ // Skip if the user already mentioned a party size
177
+ skip: ({ data }) => typeof data.guests === 'number',
178
+ },
179
+ ],
180
+ },
181
+ ],
182
+ });
183
+ ```
184
+
185
+ ### Auto step with branches and a reply step
186
+
187
+ ```typescript
188
+ import { createAgent, GeminiProvider } from '@falai/agent';
189
+
190
+ const agent = createAgent({
191
+ name: 'EligibilityRouter',
192
+ provider: new GeminiProvider({ apiKey: process.env.GEMINI_API_KEY! }),
193
+ schema: {
194
+ type: 'object',
195
+ properties: { tier: { type: 'string' } },
196
+ },
197
+ flows: [
198
+ {
199
+ title: 'Quote',
200
+ steps: [
201
+ // Pure computation — no LLM call.
202
+ {
203
+ id: 'check_tier',
204
+ auto: true,
205
+ requires: ['tier'],
206
+ branches: [
207
+ { if: ({ data }) => data.tier === 'enterprise', then: 'concierge' },
208
+ { when: 'the user already used their free trial', then: 'upsell' },
209
+ { then: 'self_serve' }, // unconditional fallback
210
+ ],
211
+ },
212
+ // Verbatim message — no LLM call.
213
+ {
214
+ id: 'concierge',
215
+ reply: 'A concierge specialist will reach out within an hour.',
216
+ },
217
+ { id: 'upsell', prompt: 'Pitch the paid plan in two short sentences.' },
218
+ { id: 'self_serve', prompt: 'Walk them through the self-serve form.' },
219
+ ],
220
+ },
221
+ ],
222
+ });
223
+ ```
224
+
225
+ ### `when` + `if`, scoped tools and instructions, hook-driven redirect
226
+
227
+ ```typescript
228
+ import { createAgent, GeminiProvider } from '@falai/agent';
229
+
230
+ const agent = createAgent({
231
+ name: 'Refunds',
232
+ provider: new GeminiProvider({ apiKey: process.env.GEMINI_API_KEY! }),
233
+ schema: {
234
+ type: 'object',
235
+ properties: {
236
+ orderId: { type: 'string' },
237
+ refundAmount: { type: 'number' },
238
+ },
239
+ },
240
+ flows: [
241
+ {
242
+ title: 'Refund',
243
+ steps: [
244
+ {
245
+ id: 'verify',
246
+ prompt: 'Look up the order and quote a refund amount.',
247
+ collect: ['orderId', 'refundAmount'],
248
+ // Run only when both signals agree the user is requesting a refund.
249
+ when: 'the user is requesting a refund',
250
+ if: ({ context }) =>
251
+ (context as { authenticated: boolean }).authenticated,
252
+ tools: ['lookup_order'],
253
+ instructions: [
254
+ { kind: 'must', prompt: 'State the refund amount before confirming.' },
255
+ { kind: 'never', prompt: 'Promise refunds without checking eligibility.' },
256
+ ],
257
+ hooks: {
258
+ // Full hook — receives HookContext, returns Directive.
259
+ finalize: ({ data }) => {
260
+ if ((data.refundAmount ?? 0) > 500) {
261
+ return { goToStep: 'manager_review' };
262
+ }
263
+ },
264
+ },
265
+ },
266
+ { id: 'manager_review', prompt: 'Hand off to a manager for approval.' },
267
+ ],
268
+ },
269
+ ],
270
+ });
271
+ ```
272
+
273
+ ### Top-level `prepare` shorthand vs `hooks.prepare`
274
+
275
+ ```typescript
276
+ // Shorthand — receives (context, data?), returns PrepareResult.
277
+ {
278
+ id: 'enrich',
279
+ auto: true,
280
+ prepare: (context, data) => ({
281
+ dataUpdate: { customerTier: lookupTier(context, data?.email) },
282
+ }),
283
+ }
284
+
285
+ // Full hook — receives HookContext, returns PreDirective.
286
+ {
287
+ id: 'enrich',
288
+ auto: true,
289
+ hooks: {
290
+ prepare: ({ context, data, dispatch }) => {
291
+ const tier = lookupTier(context, data?.email);
292
+ dispatch({ dataUpdate: { customerTier: tier } });
293
+ if (tier === 'blocked') {
294
+ return { halt: true, reply: 'This account is on hold.' };
295
+ }
296
+ },
297
+ },
298
+ }
299
+ ```
300
+
301
+ ## Errors
302
+
303
+ The `Step` constructor validates the options shape eagerly. The
304
+ following are thrown synchronously when the agent is built:
305
+
306
+ - `FlowConfigurationError` — `when` contains a function (functions
307
+ belong on `if`).
308
+ - `FlowConfigurationError` — `auto: true` is combined with `prompt`,
309
+ `collect`, `tools`, or `finalize`.
310
+ - `FlowConfigurationError` — `reply` is combined with `prompt`,
311
+ `collect`, `tools`, `finalize`, or `auto: true`.
312
+ - `FlowConfigurationError` — `branches` is empty (`[]`).
313
+ - `FlowConfigurationError` — a non-last `branches` entry has neither
314
+ `when` nor `if` (later entries would be unreachable).
315
+ - `FlowConfigurationError` — a `branches[i].then` Directive sets more
316
+ than one position field (`goTo`, `goToStep`, `complete`, `abort`,
317
+ `reset`).
318
+ - `FlowConfigurationError` — a `branches[i].then` Directive contains
319
+ an empty `goTo: {}`.
320
+
321
+ Runtime errors that surface from a step's hook execution include
322
+ `DataValidationError` (invalid collected data), `ToolExecutionError`
323
+ (a tool inside the step threw or rejected), and
324
+ `ResponseGenerationError` (LLM call failed after retries). See
325
+ [Errors](./errors.md) for handling patterns.
326
+
327
+ ## Related
328
+
329
+ - [Architecture](../concepts/architecture.md) — where Step fits among the seven primitives
330
+ - [Turn pipeline](../concepts/pipeline.md) — when each step phase fires inside a turn
331
+ - [Flow](./flow.md) — the parent type that contains a step's `steps[]` entry
332
+ - [Tool](./tool.md) — the shape consumed by `tools[]`
333
+ - [Instruction](./instruction.md) — the shape consumed by `instructions[]`
334
+ - [Branches](./branches.md) — the full `BranchEntry` / `BranchMap` contract
335
+ - [Directive](./directive.md) — the post-LLM return type for `hooks.finalize`
336
+ - [PreDirective](./pre-directive.md) — the pre-LLM return type for `hooks.onEnter` and `hooks.prepare`
337
+ - [When and if](../guides/conditions.md) — picking between AI and code conditions
338
+ - [Branching](../guides/branching.md) — adding source-local forks
339
+ - [Flow control](../guides/flow-control.md) — redirecting from a hook
@@ -0,0 +1,269 @@
1
+ ---
2
+ title: "Tool"
3
+ description: "The function-call surface the AI can invoke, with optional metadata for safety, concurrency, validation, and permissions."
4
+ type: reference
5
+ order: 4
6
+ ---
7
+
8
+ # Tool
9
+
10
+ > **Where this is introduced:** [Add tools](../start/04-add-tools.md)
11
+
12
+ A `Tool` is a function the agent can invoke during a turn. v2 unifies tools into a single interface — every metadata field is optional. The handler receives a `ToolContext` (with `dispatch` for mid-handler redirection) and may return a plain value or a `ToolResult` (with an optional `directive` for declarative redirection on return).
13
+
14
+ `Tool.id` is the sole identifier.
15
+
16
+ ## Signature
17
+
18
+ ```typescript
19
+ interface Tool<TContext = any, TData = any, TResult = any> {
20
+ // Identity
21
+ id: string;
22
+ description?: string;
23
+ parameters?: unknown;
24
+
25
+ // Handler
26
+ handler: ToolHandler<TContext, TData, TResult>;
27
+
28
+ // Optional metadata
29
+ isReadOnly?(input?: Record<string, unknown>): boolean;
30
+ isConcurrencySafe?(input?: Record<string, unknown>): boolean;
31
+ isDestructive?(input?: Record<string, unknown>): boolean;
32
+ interruptBehavior?(): 'cancel' | 'block';
33
+ maxResultSizeChars?: number;
34
+
35
+ validateInput?(
36
+ input: Record<string, unknown>,
37
+ context: ToolContext<TContext, TData>,
38
+ ): Promise<ToolValidationResult> | ToolValidationResult;
39
+
40
+ checkPermissions?(
41
+ input: Record<string, unknown>,
42
+ context: ToolContext<TContext, TData>,
43
+ ): Promise<ToolPermissionResult> | ToolPermissionResult;
44
+ }
45
+
46
+ type ToolHandler<TContext, TData, TResult> = (
47
+ ctx: ToolContext<TContext, TData>,
48
+ args?: Record<string, unknown>,
49
+ ) =>
50
+ | Promise<TResult | ToolResult<TResult, TContext, TData>>
51
+ | TResult
52
+ | ToolResult<TResult, TContext, TData>;
53
+
54
+ interface ToolContext<TContext, TData> {
55
+ context: TContext;
56
+ data: Partial<TData>;
57
+ history: Event[];
58
+ step?: StepRef;
59
+ metadata?: Record<string, unknown>;
60
+
61
+ updateContext(updates: Partial<TContext>): Promise<void>;
62
+ updateData(updates: Partial<TData>): Promise<void>;
63
+ getField<K extends keyof TData>(key: K): TData[K] | undefined;
64
+ setField<K extends keyof TData>(key: K, value: TData[K]): Promise<void>;
65
+ hasField<K extends keyof TData>(key: K): boolean;
66
+
67
+ /** Imperative redirection — emit a directive mid-handler. */
68
+ dispatch(directive: Directive<TContext, TData>): void;
69
+ }
70
+
71
+ interface ToolResult<TResultData, TContext, TData> {
72
+ data?: TResultData;
73
+ contextUpdate?: Partial<TContext>;
74
+ dataUpdate?: Partial<TData>;
75
+ success?: boolean;
76
+ error?: string;
77
+ meta?: Record<string, unknown>;
78
+ /** Declarative redirection — emit a directive on return. */
79
+ directive?: Directive<TContext, TData>;
80
+ }
81
+
82
+ interface ToolValidationResult {
83
+ valid: boolean;
84
+ error?: string;
85
+ correctedInput?: Record<string, unknown>;
86
+ }
87
+
88
+ interface ToolPermissionResult {
89
+ allowed: boolean;
90
+ reason?: string;
91
+ canOverride?: boolean;
92
+ }
93
+ ```
94
+
95
+ ## Fields
96
+
97
+ ### `Tool`
98
+
99
+ | Field | Type | Required | Default | Notes |
100
+ |-------|------|----------|---------|-------|
101
+ | `id` | `string` | yes | — | Unique identifier. The AI references this name when calling the tool. There is no separate `name` field. |
102
+ | `handler` | `ToolHandler` | yes | — | The function the AI invokes. Receives `ctx` and optional `args`. |
103
+ | `description` | `string` | no | — | Free-form description for AI tool discovery. |
104
+ | `parameters` | `unknown` | no | — | Argument schema (provider-specific shape; pass through to the LLM). |
105
+ | `isReadOnly` | `(input?) => boolean` | no | — | Returns `true` when the call has no side effects. Enables result caching and concurrency. |
106
+ | `isConcurrencySafe` | `(input?) => boolean` | no | — | Returns `true` when this call may run in parallel with other concurrent-safe calls. |
107
+ | `isDestructive` | `(input?) => boolean` | no | — | Returns `true` for irreversible operations. Surfaces to confirmation UIs. |
108
+ | `interruptBehavior` | `() => 'cancel' \| 'block'` | no | `'cancel'` | How the tool reacts to abort signals. `'block'` waits for natural completion. |
109
+ | `maxResultSizeChars` | `number` | no | — | Truncation cap for the serialized result, before history compaction. |
110
+ | `validateInput` | `(input, ctx) => ToolValidationResult` | no | — | Pre-execution input check. May return `correctedInput` to repair the call. |
111
+ | `checkPermissions` | `(input, ctx) => ToolPermissionResult` | no | — | Pre-execution gate. When `allowed: false`, the handler is **not** invoked. |
112
+
113
+ ### `ToolContext`
114
+
115
+ | Field | Type | Notes |
116
+ |-------|------|-------|
117
+ | `context` | `TContext` | Ambient app data (user, env, services). |
118
+ | `data` | `Partial<TData>` | Everything collected so far across the conversation. |
119
+ | `history` | `Event[]` | Native multi-turn history (read-only). |
120
+ | `step` | `StepRef \| undefined` | Identifies the current flow/step when the tool runs inside a flow. |
121
+ | `metadata` | `Record<string, unknown> \| undefined` | Free-form per-call metadata. |
122
+ | `updateContext` | `(updates) => Promise<void>` | Shallow-merge into `context`. Triggers context lifecycle hooks. |
123
+ | `updateData` | `(updates) => Promise<void>` | Shallow-merge into `data`. Triggers data lifecycle hooks. |
124
+ | `getField` / `setField` / `hasField` | `(key) => …` | Typed accessors over `data`. |
125
+ | `dispatch` | `(directive) => void` | Imperative directive emit. May be called multiple times; emissions are merged by Algorithm 4 alongside other tool/hook directives this turn. |
126
+
127
+ ### `ToolResult`
128
+
129
+ | Field | Type | Notes |
130
+ |-------|------|-------|
131
+ | `data` | `TResultData` | The value the AI sees as the tool result. |
132
+ | `contextUpdate` | `Partial<TContext>` | Shallow-merged into `context` after the call. |
133
+ | `dataUpdate` | `Partial<TData>` | Shallow-merged into `data` after the call. |
134
+ | `success` | `boolean` | When `false`, the executor treats this as a failed call and surfaces `error`. |
135
+ | `error` | `string` | Failure message when `success === false`. |
136
+ | `meta` | `Record<string, unknown>` | Free-form metadata (stored on the tool event). |
137
+ | `directive` | `Directive` | Declarative redirection. Equivalent to calling `ctx.dispatch(directive)` once. |
138
+
139
+ ### `ToolValidationResult`
140
+
141
+ | Field | Type | Notes |
142
+ |-------|------|-------|
143
+ | `valid` | `boolean` | `false` blocks execution and surfaces `error` to the AI. |
144
+ | `error` | `string` | Why validation failed. |
145
+ | `correctedInput` | `Record<string, unknown>` | When present, the executor retries with this input instead of the original. |
146
+
147
+ ### `ToolPermissionResult`
148
+
149
+ | Field | Type | Notes |
150
+ |-------|------|-------|
151
+ | `allowed` | `boolean` | `false` blocks execution; the handler is never called. |
152
+ | `reason` | `string` | Why permission was denied. |
153
+ | `canOverride` | `boolean` | Hint to UIs: the user may grant a one-time override. |
154
+
155
+ ## Examples
156
+
157
+ ### 1. Imperative redirection with `ctx.dispatch`
158
+
159
+ A tool that runs mid-flow and decides the rest of the turn is moot — for example, an eligibility check that fails and should jump straight to a denial flow.
160
+
161
+ ```typescript
162
+ import type { Tool } from "@falai/agent";
163
+
164
+ type Ctx = { userId: string };
165
+ type Data = { country: string };
166
+
167
+ export const checkEligibility: Tool<Ctx, Data, { ok: boolean }> = {
168
+ id: "check_eligibility",
169
+ description: "Verify the user can proceed with booking.",
170
+ isReadOnly: () => true,
171
+ async handler(ctx) {
172
+ const ok = await isEligible(ctx.context.userId, ctx.data.country);
173
+
174
+ if (!ok) {
175
+ // Imperative: stop reasoning, jump to the denial flow.
176
+ ctx.dispatch({
177
+ goTo: "denial",
178
+ reply: "Sorry — you're not eligible for this service.",
179
+ });
180
+ return { ok: false };
181
+ }
182
+
183
+ return { ok: true };
184
+ },
185
+ };
186
+ ```
187
+
188
+ ### 2. Declarative redirection with `ToolResult.directive`
189
+
190
+ The same tool, written as a value-returning handler. The directive rides back on the result and is merged identically.
191
+
192
+ ```typescript
193
+ export const checkEligibility: Tool<Ctx, Data, { ok: boolean }> = {
194
+ id: "check_eligibility",
195
+ description: "Verify the user can proceed with booking.",
196
+ isReadOnly: () => true,
197
+ async handler(ctx) {
198
+ const ok = await isEligible(ctx.context.userId, ctx.data.country);
199
+
200
+ if (!ok) {
201
+ return {
202
+ data: { ok: false },
203
+ directive: {
204
+ goTo: "denial",
205
+ reply: "Sorry — you're not eligible for this service.",
206
+ },
207
+ };
208
+ }
209
+
210
+ return { data: { ok: true } };
211
+ },
212
+ };
213
+ ```
214
+
215
+ ### 3. Validation, permissions, and write semantics
216
+
217
+ A destructive tool that validates its input, checks permissions, and writes back into `data`.
218
+
219
+ ```typescript
220
+ export const bookHotel: Tool<Ctx, Data, { id: string }> = {
221
+ id: "book_hotel",
222
+ description: "Reserve a hotel for the collected dates.",
223
+ isDestructive: () => true,
224
+ isConcurrencySafe: () => false,
225
+ maxResultSizeChars: 2_000,
226
+
227
+ validateInput(input) {
228
+ if (typeof input.nights !== "number" || input.nights < 1) {
229
+ return { valid: false, error: "`nights` must be a positive integer." };
230
+ }
231
+ return { valid: true };
232
+ },
233
+
234
+ checkPermissions(_input, ctx) {
235
+ if (!ctx.context.userId) {
236
+ return { allowed: false, reason: "Sign in required.", canOverride: false };
237
+ }
238
+ return { allowed: true };
239
+ },
240
+
241
+ async handler(ctx, args) {
242
+ const id = await api.book(ctx.context.userId, args);
243
+ return {
244
+ data: { id },
245
+ dataUpdate: { bookingId: id },
246
+ success: true,
247
+ };
248
+ },
249
+ };
250
+ ```
251
+
252
+ ## Errors
253
+
254
+ Misuse surfaces as typed errors from the executor:
255
+
256
+ - `ToolExecutionError` — handler threw, returned `success: false`, exceeded `maxResultSizeChars` after compaction, or the tool was invoked with arguments that fail `validateInput` and cannot be corrected.
257
+ - `FlowConfigurationError` — a returned `directive` is malformed (e.g., two position fields set, or `goTo` references an unknown flow/step).
258
+ - `DataValidationError` — `dataUpdate` violates the agent schema.
259
+
260
+ Permission denials (`checkPermissions` returning `allowed: false`) are surfaced as a structured tool result with `success: false` and `error: <reason>` rather than a thrown error — this keeps the AI's reasoning loop intact.
261
+
262
+ ## Related
263
+
264
+ - [Add tools](../start/04-add-tools.md) — tutorial that introduces this type.
265
+ - [Architecture](../concepts/architecture.md) — where Tool fits among the seven primitives.
266
+ - [Directives](../concepts/directives.md) — what `dispatch` and `directive` emit.
267
+ - [Directive](./directive.md) — the flat shape used by both forms above.
268
+ - [Flow control](../guides/flow-control.md) — recipes for redirecting from tools and hooks.
269
+ - [Errors](./errors.md) — `ToolExecutionError` format contract.
@@ -0,0 +1,81 @@
1
+ ---
2
+ title: "Install"
3
+ description: "Install @falai/agent, set up your environment, and grab a provider key."
4
+ type: tutorial
5
+ order: 1
6
+ ---
7
+
8
+ # Install
9
+
10
+ Before you write a flow or define a schema, you need `@falai/agent` in your project and a provider key in your environment. This page handles both. By the end you will have a verified provider instance and a clean slate for the agent you build on the next page.
11
+
12
+ ## Prerequisites
13
+
14
+ - Node.js **18+** or Bun **1.0+**
15
+ - A package manager (Bun, npm, pnpm, or yarn)
16
+ - An API key from at least one provider — see [Provider keys](#provider-keys) below
17
+
18
+ ## Install the package
19
+
20
+ ```bash
21
+ bun add @falai/agent
22
+ ```
23
+
24
+ Or, with another package manager:
25
+
26
+ ```bash
27
+ npm install @falai/agent
28
+ # or
29
+ pnpm add @falai/agent
30
+ # or
31
+ yarn add @falai/agent
32
+ ```
33
+
34
+ The package ships ESM and CJS entry points and bundles its TypeScript types — there is no `@types/*` companion to install.
35
+
36
+ ## Set up your environment
37
+
38
+ Create a `.env` file at the root of your project. You only need a key for the provider you plan to use.
39
+
40
+ ```bash
41
+ # .env
42
+ GEMINI_API_KEY=your-gemini-key
43
+ OPENAI_API_KEY=your-openai-key
44
+ ANTHROPIC_API_KEY=your-anthropic-key
45
+ OPENROUTER_API_KEY=your-openrouter-key # optional broker
46
+ ```
47
+
48
+ Load the file before your agent code runs. Bun reads `.env` automatically; with Node, pass `--env-file=.env` (Node 20+) or use your tool of choice.
49
+
50
+ ## Provider keys
51
+
52
+ Pick one provider to start. The tutorial uses Gemini by default because it has the fastest free tier; swap to another vendor by changing one constructor in [Your first agent](./02-first-agent.md).
53
+
54
+ - **Google Gemini** — [Gemini Studio](https://aistudio.google.com/apikey) (`GEMINI_API_KEY`)
55
+ - **OpenAI** — [OpenAI Platform](https://platform.openai.com/api-keys) (`OPENAI_API_KEY`)
56
+ - **Anthropic** — [Anthropic Console](https://console.anthropic.com/settings/keys) (`ANTHROPIC_API_KEY`)
57
+ - **OpenRouter** *(optional broker for many vendors behind one key)* — [OpenRouter](https://openrouter.ai/keys) (`OPENROUTER_API_KEY`)
58
+
59
+ Any one of these is enough to finish the tutorial. The [Providers reference](../reference/providers.md) covers options like `backupModels` and per-vendor `config`.
60
+
61
+ ## Verify the install
62
+
63
+ Drop this into `src/check.ts` and run it. If it prints `Provider ready`, you are set.
64
+
65
+ ```typescript
66
+ import { GeminiProvider } from "@falai/agent";
67
+
68
+ const provider = new GeminiProvider({
69
+ apiKey: process.env.GEMINI_API_KEY!,
70
+ model: "models/gemini-2.5-pro",
71
+ });
72
+
73
+ console.log("Provider ready:", provider.constructor.name);
74
+ ```
75
+
76
+ ```bash
77
+ bun run src/check.ts
78
+ # Provider ready: GeminiProvider
79
+ ```
80
+
81
+ **Next:** [Your first agent](./02-first-agent.md)