@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,122 @@
1
+ ---
2
+ title: "Errors"
3
+ description: "Typed error classes the framework throws, and the message format contract every thrown error follows."
4
+ type: reference
5
+ order: 12
6
+ ---
7
+
8
+ # Errors
9
+
10
+ > **Where this is introduced:** [Errors](../guides/error-handling.md)
11
+
12
+ `@falai/agent` throws typed `Error` subclasses for every failure mode the framework owns. Catch them by class to discriminate construction errors from runtime errors, and by `error.name` when classes that are not exported (e.g. `DataValidationError`, `ResponseGenerationError`) need to be matched.
13
+
14
+ Every thrown message follows the same format contract:
15
+
16
+ ```text
17
+ [<ErrorClass>] <what>: <why>. <how to fix>.
18
+ ```
19
+
20
+ The bracketed prefix matches the class name. The "what / why / how to fix" triplet is mandatory — the framework never throws a bare message.
21
+
22
+ ## Signature
23
+
24
+ ```typescript
25
+ // Exported from "@falai/agent"
26
+ class FlowConfigurationError extends Error { /* name = "FlowConfigurationError" */ }
27
+ class ToolCreationError extends Error { toolId: string; cause?: Error }
28
+ class ToolExecutionError extends Error {
29
+ toolId: string;
30
+ executionContext?: Record<string, unknown>;
31
+ cause?: Error;
32
+ }
33
+ class NotImplementedError extends Error { /* name = "NotImplementedError" */ }
34
+
35
+ // Internal — match by `error.name` (not exported from the package barrel)
36
+ class DataValidationError extends Error { errors: ValidationError[] }
37
+ class ResponseGenerationError extends Error {
38
+ details?: {
39
+ originalError?: unknown;
40
+ params?: Record<string, unknown>;
41
+ phase?: string;
42
+ context?: Record<string, unknown>;
43
+ };
44
+ }
45
+ ```
46
+
47
+ ## Fields
48
+
49
+ | Class | Thrown when | Notable fields | Recover by |
50
+ |-------|-------------|----------------|------------|
51
+ | `FlowConfigurationError` | Construction- or run-time misconfiguration: duplicate ids, unknown `collect` keys, malformed `Directive`, auto-step cycles, branch targets that do not resolve, function on `when`. | `message` | Fix the offending agent/flow/step/branch/directive at the source. Not a runtime-recoverable error. |
52
+ | `ToolCreationError` | A `Tool` fails registration (invalid schema, duplicate id, builder threw). | `toolId`, `cause` | Repair the tool definition. Not user-facing. |
53
+ | `ToolExecutionError` | A handler throws, all retries fail, or `validateInput` cannot correct invalid args. | `toolId`, `executionContext`, `cause` | Surface a user-friendly message; optionally `agent.dispatch({ goTo: '<recovery-flow>' })`. |
54
+ | `DataValidationError` | `agent.respond(...)` collects values that violate the declared `schema`. | `errors: ValidationError[]` | Re-prompt for the offending fields, then retry. |
55
+ | `ResponseGenerationError` | The provider call fails or the response cannot be parsed. | `details.phase`, `details.originalError` | Retry with backoff, fall back to a different provider, or surface a soft failure to the user. |
56
+ | `NotImplementedError` | A reserved option is set to a value this version does not support (e.g. `routerMode: 'embedding'` in v2.0). | `message` | Use a supported value. |
57
+
58
+ ## Examples
59
+
60
+ ### 1. Narrowing by class and `name`
61
+
62
+ ```typescript
63
+ import {
64
+ FlowConfigurationError,
65
+ ToolExecutionError,
66
+ NotImplementedError,
67
+ } from "@falai/agent";
68
+
69
+ try {
70
+ const response = await agent.respond(message);
71
+ return response.message;
72
+ } catch (err) {
73
+ if (err instanceof FlowConfigurationError) throw err; // bug — bubble up
74
+ if (err instanceof NotImplementedError) throw err; // config bug
75
+ if (err instanceof ToolExecutionError) {
76
+ log.warn({ toolId: err.toolId, cause: err.cause }, err.message);
77
+ return "Sorry, that action failed. Try again in a moment.";
78
+ }
79
+ // Not exported — match by name.
80
+ if (err instanceof Error && err.name === "DataValidationError") {
81
+ return "I need you to clarify a few details — let's try that again.";
82
+ }
83
+ if (err instanceof Error && err.name === "ResponseGenerationError") {
84
+ return "I'm having trouble reaching the model. Please retry.";
85
+ }
86
+ throw err;
87
+ }
88
+ ```
89
+
90
+ ### 2. The format contract in practice
91
+
92
+ Every thrown message is parseable. The leading `[<ErrorClass>]` token mirrors the class name, the colon separates `<what>` from `<why>`, and the trailing sentence is `<how to fix>`.
93
+
94
+ ```text
95
+ [FlowConfigurationError] Invalid directive: multiple position fields set (goTo, complete). A directive may have at most one position field. Remove the extras.
96
+
97
+ [ToolExecutionError] Tool "book_hotel" execution failed: all 3 attempts exhausted. Check the tool handler for errors or increase maxRetries. Last error: ECONNRESET.
98
+
99
+ [DataValidationError] Data validation failed: fields [checkIn must be a date] did not pass schema validation. Fix the offending values to match the declared schema.
100
+
101
+ [NotImplementedError] routerMode "embedding" is not implemented: only "ai" is supported in v2.0. Set routerMode to "ai" or omit the option.
102
+ ```
103
+
104
+ ## Errors
105
+
106
+ The format contract itself has zero runtime enforcement — it is a contract on framework code, not on user code. If you write a custom `Tool` or hook that throws, follow the same shape so downstream `try/catch` blocks parse uniformly:
107
+
108
+ ```typescript
109
+ throw new ToolExecutionError(
110
+ `[ToolExecutionError] Tool "${tool.id}" booking failed: provider returned 503. Retry the call or fall back to manual booking.`,
111
+ tool.id,
112
+ );
113
+ ```
114
+
115
+ Tool input validation, permission denials, and missing-tool warnings are reported as `ToolResult { success: false, error }` rather than thrown — this keeps the AI's reasoning loop intact while preserving the same `[<ErrorClass>] <what>: <why>. <how to fix>.` shape in the `error` string.
116
+
117
+ ## Related
118
+
119
+ - [Errors](../guides/error-handling.md) — recipe-shaped guide that introduces this surface.
120
+ - [createAgent](./create-agent.md) — construction-time errors thrown from `new Agent(...)`.
121
+ - [Tool](./tool.md) — handler return shape and the `ToolExecutionError` triggers.
122
+ - [Directive](./directive.md) — the validation rules that surface as `FlowConfigurationError`.
@@ -0,0 +1,238 @@
1
+ ---
2
+ title: Flow
3
+ description: A goal-shaped sequence of steps with shared schema, conditions, and completion semantics.
4
+ type: reference
5
+ order: 2
6
+ ---
7
+
8
+ # Flow
9
+
10
+ > **Where this is introduced:** [Architecture](../concepts/architecture.md)
11
+
12
+ A `Flow` is one of the seven primitives in `@falai/agent`. It models a single conversational goal — booking a hotel, escalating a complaint, onboarding a teammate — as an ordered set of steps that share the agent's typed `TData` schema. Flows declare what data they need (`requiredFields`), what extra data they can use (`optionalFields`), when they should activate (`when` for AI strings, `if` for code), and what happens when they finish (`onComplete` or `hooks.onComplete`). The router selects exactly one flow per turn; once the active flow's required fields are satisfied, the engine fires its completion path.
13
+
14
+ ## Signature
15
+
16
+ ```typescript
17
+ interface FlowOptions<TContext = unknown, TData = unknown> {
18
+ id?: string;
19
+ title: string;
20
+ description?: string;
21
+
22
+ when?: ConditionWhen; // string | string[]
23
+ if?: ConditionIf<TContext, TData>; // predicate | predicate[]
24
+
25
+ instructions?: Instruction<TContext, TData>[];
26
+ tools?: (string | Tool<TContext, TData>)[];
27
+
28
+ routingExtrasSchema?: StructuredSchema;
29
+ responseOutputSchema?: StructuredSchema;
30
+
31
+ requiredFields?: (keyof TData)[];
32
+ optionalFields?: (keyof TData)[];
33
+ initialData?: Partial<TData>;
34
+
35
+ steps?: StepOptions<TContext, TData>[];
36
+
37
+ onComplete?: string; // top-level: string sugar only
38
+ reentrant?: boolean; // default false
39
+
40
+ hooks?: FlowLifecycleHooks<TContext, TData>;
41
+ }
42
+
43
+ class Flow<TContext = unknown, TData = unknown> {
44
+ readonly id: string;
45
+ readonly title: string;
46
+ readonly description?: string;
47
+ readonly when?: ConditionWhen;
48
+ readonly if?: ConditionIf<TContext, TData>;
49
+ readonly initialStep: Step<TContext, TData>;
50
+ readonly requiredFields?: (keyof TData)[];
51
+ readonly optionalFields?: (keyof TData)[];
52
+ readonly initialData?: Partial<TData>;
53
+ readonly onComplete?: string;
54
+ readonly reentrant: boolean;
55
+ readonly hooks?: FlowLifecycleHooks<TContext, TData>;
56
+
57
+ constructor(options: FlowOptions<TContext, TData>, parentAgent?: Agent<TContext, TData>);
58
+
59
+ addStep(options: StepOptions<TContext, TData>): Step<TContext, TData>;
60
+ getSteps(): Step<TContext, TData>[];
61
+ getStep(stepId: string): Step<TContext, TData> | undefined;
62
+ getInstructions(): Instruction<TContext, TData>[];
63
+ getTools(): Tool<TContext, TData>[];
64
+
65
+ isComplete(data: Partial<TData>): boolean;
66
+ getMissingRequiredFields(data: Partial<TData>): (keyof TData)[];
67
+ getCompletionProgress(data: Partial<TData>): number;
68
+ }
69
+ ```
70
+
71
+ ## Fields
72
+
73
+ ### `FlowOptions`
74
+
75
+ | Field | Type | Required | Default | Notes |
76
+ | --------------------- | ------------------------------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
77
+ | `id` | `string` | no | derived from `title` | Stable identifier. Auto-generated deterministically from the title when omitted. |
78
+ | `title` | `string` | yes | — | Human-readable name. Shown to the router and used as the default flow id. |
79
+ | `description` | `string` | no | — | One-line summary surfaced to the router prompt. |
80
+ | `when` | `string \| string[]` | no | — | AI-evaluated activation condition(s). Strings only — functions belong on `if`. Multiple strings combine with AND semantics. |
81
+ | `if` | `(ctx) => boolean \| Promise<boolean>` or array | no | — | Code-evaluated activation condition(s). Free to evaluate. When both are set, `if` runs first; `when` only evaluates if `if` passes. |
82
+ | `instructions` | `Instruction<TContext, TData>[]` | no | `[]` | Flow-scoped instructions. Apply only while this flow is active. See [Instruction](./instruction.md). |
83
+ | `tools` | `(string \| Tool)[]` | no | `[]` | Tool ids (resolved via the agent's tool registry) or inline `Tool` objects. Available only while this flow is active. |
84
+ | `routingExtrasSchema` | `StructuredSchema` | no | — | Optional extra fields the router may extract during routing. |
85
+ | `responseOutputSchema`| `StructuredSchema` | no | — | Optional structured response shape for this flow's assistant messages. |
86
+ | `requiredFields` | `(keyof TData)[]` | no | — | Fields that must be present in `session.data` for the flow to complete. Drives `isComplete` and progress calculation. |
87
+ | `optionalFields` | `(keyof TData)[]` | no | — | Fields the flow uses but doesn't require. Tracked for re-entry resets and progress visibility only. |
88
+ | `initialData` | `Partial<TData>` | no | — | Pre-populated values applied when the flow is entered. Merged into `session.data`. |
89
+ | `steps` | `StepOptions<TContext, TData>[]` | no | — | Sequential steps. The first becomes the initial step; the rest are chained as linear successors. The last step is the implicit terminus. |
90
+ | `onComplete` | `string` | no | — | **String only.** Sugar for `hooks.onComplete = () => ({ goTo: '<id>' })`. For dynamic completion logic, use `hooks.onComplete`. |
91
+ | `reentrant` | `boolean` | no | `false` | If `true`, the router may select this flow again after it has completed in the current session. On re-entry, declared `requiredFields` and `optionalFields` are cleared. |
92
+ | `hooks` | `FlowLifecycleHooks<TContext, TData>` | no | — | Lifecycle hooks: `onEnter`, `onExit`, `onComplete`, `onDataUpdate`, `onContextUpdate`. See below. |
93
+
94
+ ### `FlowLifecycleHooks`
95
+
96
+ | Hook | Returns | Phase | Notes |
97
+ | ----------------- | -------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- |
98
+ | `onEnter` | `void \| PreDirective` | pre-LLM | Fires when the flow is entered. May augment the prompt, inject tools, or `halt`. See [PreDirective](./pre-directive.md).|
99
+ | `onExit` | `void` | post | Informational. Receives an `ExitReason`; cannot influence flow control. |
100
+ | `onComplete` | `void \| Directive` | post-LLM | Handler form of completion. Mutually exclusive with top-level `onComplete: string` — setting both throws. |
101
+ | `onDataUpdate` | `Partial<TData>` | post | Mutate or enrich the data update before it is committed to `session.data`. |
102
+ | `onContextUpdate` | `void` | post | Informational reaction to context updates while this flow is active. |
103
+
104
+ ### `Flow` instance methods
105
+
106
+ | Method | Returns | Notes |
107
+ | -------------------------------------------- | -------------------------------- | -------------------------------------------------------------------------------------------------- |
108
+ | `addStep(options)` | `Step<TContext, TData>` | Imperatively append a step as the successor of the current last step. Same validations as `steps[]`. |
109
+ | `getSteps()` | `Step<TContext, TData>[]` | All steps reachable from the initial step via BFS traversal. |
110
+ | `getStep(stepId)` | `Step \| undefined` | Look up a step by id. |
111
+ | `getInstructions()` | `Instruction[]` | Flow-scoped instructions (a copy). |
112
+ | `getTools()` | `Tool[]` | Flow-scoped tools (a copy). |
113
+ | `isComplete(data)` | `boolean` | `true` when all `requiredFields` are populated. Optional-only flows complete on terminus, not data. |
114
+ | `getMissingRequiredFields(data)` | `(keyof TData)[]` | Fields from `requiredFields` not yet present in `data`. |
115
+ | `getCompletionProgress(data)` | `number` (0–1) | Fraction of `requiredFields` satisfied. `0` when only `optionalFields` are declared. |
116
+
117
+ ### Completion semantics
118
+
119
+ A flow finishes in one of three ways:
120
+
121
+ 1. **All `requiredFields` are satisfied.** The engine marks the flow complete, fires `hooks.onComplete` (or the desugared `onComplete: string` transition), and applies the returned `Directive`.
122
+ 2. **The last step in `steps[]` runs and `requiredFields` is empty.** The terminus rule applies — the flow is implicitly complete, and the same completion path runs.
123
+ 3. **A `Directive` with `complete: true` is returned** from a tool, hook, or branch while the flow is active. Completion fires immediately regardless of field state.
124
+
125
+ `requiredFields` is the contract for "this flow is done." `optionalFields` is descriptive metadata — it never gates completion, but it's tracked for two reasons:
126
+
127
+ - **Re-entry resets.** When `reentrant: true` and the router re-selects this flow after it has completed, every field listed in `requiredFields` and `optionalFields` is cleared so the flow starts fresh.
128
+ - **Progress visibility.** `getCompletionProgress` ignores optional fields by design — progress reflects what the flow is *blocked on*, not what it has *touched*.
129
+
130
+ ### `reentrant` behavior
131
+
132
+ By default (`reentrant: false`), once a flow completes the router excludes it from candidate selection for the rest of the session. Set `reentrant: true` to support patterns like "book another?", "file another ticket?", or "search again". On re-entry:
133
+
134
+ - All `requiredFields` and `optionalFields` are cleared from `session.data`.
135
+ - Other fields in `session.data` are preserved.
136
+ - The flow restarts from its initial step.
137
+
138
+ `onComplete` always wins over `reentrant`. If `onComplete` (or `hooks.onComplete`) returns a target, the session transitions there. `reentrant` is consulted only when the completion handler is absent or returns `undefined`.
139
+
140
+ ### Top-level `onComplete` vs `hooks.onComplete`
141
+
142
+ The top-level `onComplete` is **string-only** sugar. Internally, the constructor desugars `onComplete: 'targetFlow'` into `hooks.onComplete = () => ({ goTo: 'targetFlow' })`. Use the handler form when you need conditional transitions, data writes, or any logic beyond a static target id.
143
+
144
+ | Use this | When |
145
+ | ------------------ | ----------------------------------------------------------------------------------- |
146
+ | `onComplete: 'id'` | You always want to chain into the same next flow when this one finishes. |
147
+ | `hooks.onComplete` | The next flow depends on collected data, or you want to write state on completion. |
148
+
149
+ > Setting **both** the top-level `onComplete` and `hooks.onComplete` on the same flow throws `FlowConfigurationError` at construction time. Pick one.
150
+
151
+ ## Examples
152
+
153
+ ### Basic linear flow
154
+
155
+ ```typescript
156
+ import { createAgent, Flow, GeminiProvider } from "@falai/agent";
157
+
158
+ interface BookingData {
159
+ destination: string;
160
+ checkIn: string;
161
+ guests: number;
162
+ }
163
+
164
+ const bookHotel = new Flow<unknown, BookingData>({
165
+ title: "Book Hotel",
166
+ description: "Collect destination, check-in date, and party size, then book.",
167
+ when: "the user wants to book a hotel",
168
+ requiredFields: ["destination", "checkIn", "guests"],
169
+ steps: [
170
+ { description: "Greet and ask destination", collect: ["destination"] },
171
+ { description: "Ask check-in date", collect: ["checkIn"] },
172
+ { description: "Ask guest count", collect: ["guests"] },
173
+ ],
174
+ });
175
+
176
+ const agent = createAgent<unknown, BookingData>({
177
+ schema: { /* ... */ },
178
+ provider: new GeminiProvider({ apiKey: process.env.GEMINI_API_KEY! }),
179
+ flows: [bookHotel],
180
+ });
181
+ ```
182
+
183
+ ### Completion handler with state writes and chained transition
184
+
185
+ ```typescript
186
+ import { Flow } from "@falai/agent";
187
+
188
+ const bookHotel = new Flow<AppContext, BookingData>({
189
+ title: "Book Hotel",
190
+ requiredFields: ["destination", "checkIn", "guests"],
191
+ reentrant: true, // allow "book another?" loops
192
+ steps: [/* ... */],
193
+ hooks: {
194
+ onComplete: ({ data }) => ({
195
+ dataUpdate: { lastBookedAt: new Date().toISOString() },
196
+ goTo: data.guests > 4 ? "Group Coordination" : "Confirmation",
197
+ reason: "booking finalized",
198
+ }),
199
+ },
200
+ });
201
+ ```
202
+
203
+ ### Imperative `addStep` after construction
204
+
205
+ ```typescript
206
+ const supportFlow = new Flow({
207
+ title: "Support",
208
+ steps: [{ description: "Capture issue summary", collect: ["issue"] }],
209
+ });
210
+
211
+ // Later — extend the flow programmatically.
212
+ supportFlow.addStep({
213
+ description: "Triage severity",
214
+ collect: ["severity"],
215
+ });
216
+ ```
217
+
218
+ > Calling `addStep` after the agent has handled a turn emits a debug-level warning that the flow graph is being mutated mid-session. The new step is still registered and connected as the successor of the current last step.
219
+
220
+ ## Errors
221
+
222
+ | Error | When it's thrown |
223
+ | --------------------------- | ------------------------------------------------------------------------------------------------------------------- |
224
+ | `FlowConfigurationError` | Both top-level `onComplete` and `hooks.onComplete` are set on the same flow. |
225
+ | `FlowConfigurationError` | A function appears in `when` (functions belong on `if`). |
226
+ | `FlowConfigurationError` | A step inside `steps[]` violates auto-step or reply-step shape rules (raised from the underlying `Step` constructor). |
227
+
228
+ All `FlowConfigurationError` messages follow the format `[FlowConfigurationError] <what>: <why>. <how to fix>.` See [Errors](./errors.md).
229
+
230
+ ## Related
231
+
232
+ - [Architecture](../concepts/architecture.md) — where Flow fits among the seven primitives
233
+ - [Turn pipeline](../concepts/pipeline.md) — when flows are selected, entered, and completed
234
+ - [Step](./step.md) — the inner DSL primitive flows are composed of
235
+ - [Directive](./directive.md) — what `hooks.onComplete` returns
236
+ - [Instruction](./instruction.md) — flow-scoped behavioral nudges
237
+ - [Branching](../guides/branching.md) — explicit forks inside a flow
238
+ - [Flow control](../guides/flow-control.md) — completion, dispatch, and verbatim replies
@@ -0,0 +1,177 @@
1
+ ---
2
+ title: "Instruction"
3
+ description: "Unified behavioral primitive that shapes how the agent responds, with a kind discriminator (must / never / should) and agent / flow / step scoping."
4
+ type: reference
5
+ order: 5
6
+ ---
7
+
8
+ # Instruction
9
+
10
+ > **Where this is introduced:** [Instructions](../guides/instructions.md)
11
+
12
+ An `Instruction` is a single statement of behavior the agent should follow. v2 collapses three v1 types into one — every instruction now carries a `kind` discriminator (`'must'`, `'never'`, or `'should'`) and a `prompt` that is rendered into the system prompt with a scope caption. The same shape works at agent, flow, and step scope; only its position in the configuration changes.
13
+
14
+ The set of instructions actually rendered into a given turn's prompt is reported back on the response as `appliedInstructions` — observability is deterministic, derived from rendering, not self-reported by the model.
15
+
16
+ ## Signature
17
+
18
+ ```typescript
19
+ interface Instruction<TContext = unknown, TData = unknown> {
20
+ id?: string;
21
+ kind?: 'must' | 'never' | 'should'; // default: 'should'
22
+ when?: ConditionWhen; // AI-evaluated string(s), AND semantics
23
+ if?: ConditionIf<TContext, TData>; // code-evaluated function(s), AND semantics
24
+ prompt: Template<TContext, TData>;
25
+ enabled?: boolean; // default: true
26
+ tags?: string[];
27
+ metadata?: Record<string, unknown>;
28
+ }
29
+
30
+ interface ScopedInstructions<TContext = unknown, TData = unknown> {
31
+ global: Instruction<TContext, TData>[];
32
+ flow?: { flowTitle: string; items: Instruction<TContext, TData>[] };
33
+ step?: { stepId: string; items: Instruction<TContext, TData>[] };
34
+ }
35
+
36
+ interface AppliedInstruction {
37
+ id: string;
38
+ scope: 'global' | 'flow' | 'step';
39
+ scopeRef?: string; // flowTitle for flow, stepId for step
40
+ }
41
+ ```
42
+
43
+ ## Fields
44
+
45
+ ### `Instruction`
46
+
47
+ | Field | Type | Required | Default | Notes |
48
+ |-------|------|----------|---------|-------|
49
+ | `prompt` | `Template<TContext, TData>` | yes | — | Behavioral text rendered into the prompt under the `## Instructions` section. |
50
+ | `kind` | `'must' \| 'never' \| 'should'` | no | `'should'` | Severity. `'must'` = absolute do, `'never'` = absolute don't, `'should'` = conditional nudge. |
51
+ | `when` | `ConditionWhen` | no | — | AI-evaluated activation string (or array, AND semantics). Functions are not allowed here; use `if`. |
52
+ | `if` | `ConditionIf<TContext, TData>` | no | — | Code-evaluated activation function (or array). Free to evaluate. When both `when` and `if` are set, `if` runs first; `when` is only evaluated if `if` passes. |
53
+ | `id` | `string` | no | auto | Stable identifier used in `AppliedInstruction.id`. Auto-generated when omitted. |
54
+ | `enabled` | `boolean` | no | `true` | Set `false` to skip the instruction without removing it from configuration. |
55
+ | `tags` | `string[]` | no | — | Free-form tags for filtering and grouping. |
56
+ | `metadata` | `Record<string, unknown>` | no | — | Free-form per-instruction metadata. |
57
+
58
+ ### `AppliedInstruction`
59
+
60
+ | Field | Type | Notes |
61
+ |-------|------|-------|
62
+ | `id` | `string` | The `Instruction.id` that fired. |
63
+ | `scope` | `'global' \| 'flow' \| 'step'` | Where the instruction was declared. |
64
+ | `scopeRef` | `string \| undefined` | `flowTitle` for `flow`, `stepId` for `step`, `undefined` for `global`. |
65
+
66
+ ## Scoping
67
+
68
+ The same `Instruction` shape attaches at three positions:
69
+
70
+ - **Agent (global):** `AgentOptions.instructions` — always considered, on every turn, for every flow.
71
+ - **Flow:** `FlowOptions.instructions` — considered when the active flow matches.
72
+ - **Step:** `StepOptions.instructions` — considered when the active step matches.
73
+
74
+ At prompt-build time the composer renders each active instruction as a single bullet:
75
+
76
+ ```
77
+ - [<kind>] [<scope-caption>] <prompt>
78
+ ```
79
+
80
+ Scope captions are fixed by where the instruction was declared:
81
+
82
+ | Scope | Caption |
83
+ |-------|---------|
84
+ | Agent | `[Always]` |
85
+ | Flow | `[In: <FlowTitle>]` |
86
+ | Step | `[Step: <stepId>]` |
87
+
88
+ Example block in the rendered prompt:
89
+
90
+ ```
91
+ ## Instructions
92
+
93
+ - [must] [Always] Always greet by name
94
+ - [never] [Always] Promise delivery dates you cannot guarantee
95
+ - [should] [In: Booking] Confirm dates before calling book_hotel
96
+ - [should] [Step: payment] If the card is declined, never retry without confirmation
97
+ ```
98
+
99
+ ## Examples
100
+
101
+ ### 1. Agent-level absolutes plus a step-level nudge
102
+
103
+ ```typescript
104
+ import { createAgent, GeminiProvider } from '@falai/agent';
105
+
106
+ const agent = createAgent({
107
+ name: 'BookingBot',
108
+ provider: new GeminiProvider({ apiKey: process.env.GEMINI_API_KEY! }),
109
+ instructions: [
110
+ { kind: 'must', prompt: 'Validate dates are in the future before booking.' },
111
+ { kind: 'never', prompt: 'Promise rates you have not looked up.' },
112
+ ],
113
+ flows: [
114
+ {
115
+ title: 'Booking',
116
+ instructions: [
117
+ { kind: 'should', prompt: 'Offer to compare two options before committing.' },
118
+ ],
119
+ steps: [
120
+ {
121
+ id: 'payment',
122
+ prompt: 'Take payment.',
123
+ instructions: [
124
+ { kind: 'must', prompt: 'If the card is declined, never retry without confirmation.' },
125
+ ],
126
+ },
127
+ ],
128
+ },
129
+ ],
130
+ });
131
+ ```
132
+
133
+ ### 2. Conditional activation with `when` and `if`
134
+
135
+ ```typescript
136
+ import type { Instruction } from '@falai/agent';
137
+
138
+ type Ctx = { tier: 'free' | 'pro' };
139
+ type Data = { hasQuoted: boolean };
140
+
141
+ const concise: Instruction<Ctx, Data> = {
142
+ kind: 'should',
143
+ when: 'User asks a simple yes/no question',
144
+ prompt: 'Answer in one sentence.',
145
+ };
146
+
147
+ const proOnly: Instruction<Ctx, Data> = {
148
+ kind: 'must',
149
+ if: (ctx) => ctx.context.tier === 'pro',
150
+ prompt: 'Offer to export the conversation as PDF.',
151
+ };
152
+ ```
153
+
154
+ ### 3. Reading `appliedInstructions` from a response
155
+
156
+ ```typescript
157
+ const response = await agent.respond('Hi, I want to book a room.');
158
+
159
+ for (const a of response.appliedInstructions ?? []) {
160
+ console.log(`${a.scope}${a.scopeRef ? `:${a.scopeRef}` : ''} → ${a.id}`);
161
+ }
162
+ // global → ins_validate_dates
163
+ // flow:Booking → ins_offer_two_options
164
+ ```
165
+
166
+ ## Errors
167
+
168
+ - `FlowConfigurationError` — duplicate `id` across instructions in the same scope, or `kind` set to a value other than `'must' | 'never' | 'should'`.
169
+ - `DataValidationError` — a `Template` `prompt` references a `data` field not declared in the agent `schema`.
170
+
171
+ ## Related
172
+
173
+ - [Instructions](../guides/instructions.md) — recipe for shaping behavior with `must` / `never` / `should`
174
+ - [Architecture](../concepts/architecture.md) — where Instruction fits among the seven primitives
175
+ - [createAgent](./create-agent.md) — `AgentOptions.instructions`
176
+ - [Flow](./flow.md) — `FlowOptions.instructions`
177
+ - [Step](./step.md) — `StepOptions.instructions`
@@ -0,0 +1,131 @@
1
+ ---
2
+ title: "PreDirective"
3
+ description: "Directive variant returned by pre-LLM hooks; adds prompt and tool shaping for the current turn."
4
+ type: reference
5
+ order: 7
6
+ ---
7
+
8
+ # PreDirective
9
+
10
+ > **Where this is introduced:** [Directives](../concepts/directives.md)
11
+
12
+ `PreDirective<TContext, TData>` is the variant of [`Directive`](./directive.md)
13
+ that pre-LLM hooks return. It inherits every Directive field — position writes
14
+ (`goTo`, `goToStep`, `complete`, `abort`, `reset`), the verbatim `reply`, and
15
+ state writes (`dataUpdate`, `contextUpdate`) — and adds three fields that only
16
+ make sense before this turn's LLM call: `appendPrompt`, `injectTools`, and
17
+ `halt`.
18
+
19
+ Lifetime is one turn. PreDirective fields are stripped before
20
+ `session.pendingDirective` is written, so they cannot persist across turns and
21
+ cannot be assigned to `pendingDirective` directly.
22
+
23
+ PreDirective is the return type of:
24
+
25
+ - `flow.hooks.onEnter`
26
+ - `step.hooks.onEnter`
27
+ - `step.hooks.prepare`
28
+ - the merged pre-LLM phase of the directive bus
29
+ - a [`Signal`](./signals.md) firing in the pre-phase (via `SignalDirective`,
30
+ which extends PreDirective)
31
+
32
+ Post-LLM hooks (`step.hooks.finalize`, `flow.hooks.onComplete`) return plain
33
+ `Directive` — the three PreDirective-only fields have no effect post-LLM and
34
+ are dropped with a debug log if present.
35
+
36
+ ## Signature
37
+
38
+ ```typescript
39
+ interface PreDirective<TContext = unknown, TData = unknown>
40
+ extends Directive<TContext, TData> {
41
+ appendPrompt?: string[];
42
+ injectTools?: Array<Tool<TContext, TData>>;
43
+ halt?: boolean;
44
+ }
45
+ ```
46
+
47
+ ## Fields
48
+
49
+ | Field | Type | Required | Default | Notes |
50
+ |-------|------|----------|---------|-------|
51
+ | `appendPrompt` | `string[]` | no | — | Sentences appended to the system prompt for THIS turn only via `PromptComposer`'s transient appendage slot. Merged across hooks by array-concat (Algorithm 4). Never cached, never persisted. |
52
+ | `injectTools` | `Tool<TContext, TData>[]` | no | — | Tools added to the available tool list for THIS turn only via `ToolManager`'s transient layer. Merged across hooks by concat-then-dedupe by `Tool.id` (last definition wins). Tool references are not serializable, so this field never persists. |
53
+ | `halt` | `boolean` | no | `false` | When `true`, skip the LLM call entirely this turn. Merged by logical-OR. Co-validates with `reply`: if both are set the `reply` is emitted and the turn ends with `stoppedReason: 'reply'`; if `halt` is set without `reply` the turn ends with `stoppedReason: 'halt'` and an empty assistant message. |
54
+ | *…all `Directive` fields* | — | — | — | See [Directive](./directive.md) for `goTo`, `goToStep`, `complete`, `abort`, `reset`, `reply`, `dataUpdate`, `contextUpdate`. Mutually-exclusive position rules apply identically. |
55
+
56
+ ## Examples
57
+
58
+ ### Append a sentence to the prompt for this turn
59
+
60
+ ```typescript
61
+ import type { PreDirective } from '@falai/agent';
62
+
63
+ const flow = {
64
+ title: 'Booking',
65
+ hooks: {
66
+ onEnter: (ctx): PreDirective => {
67
+ if (ctx.context.user.tier === 'vip') {
68
+ return {
69
+ appendPrompt: ['This caller is a VIP — confirm preferences before suggesting options.'],
70
+ };
71
+ }
72
+ },
73
+ },
74
+ steps: [/* ... */],
75
+ };
76
+ ```
77
+
78
+ ### Inject a one-shot tool, then halt the LLM call
79
+
80
+ ```typescript
81
+ import type { PreDirective, Tool } from '@falai/agent';
82
+
83
+ const lookupAccount: Tool = {
84
+ id: 'lookup_account',
85
+ description: 'Fetch the caller\'s account record.',
86
+ parameters: { type: 'object', properties: {} },
87
+ handler: async (ctx) => ({ content: JSON.stringify(await fetchAccount(ctx.context.user.id)) }),
88
+ };
89
+
90
+ const step = {
91
+ id: 'verify',
92
+ prompt: 'Verify the caller before proceeding.',
93
+ hooks: {
94
+ prepare: async (ctx): Promise<PreDirective> => {
95
+ if (!ctx.data.verified) {
96
+ // Make the tool available for THIS turn only and let the model call it.
97
+ return { injectTools: [lookupAccount] };
98
+ }
99
+ // Already verified — skip the LLM, emit a deterministic reply.
100
+ return { halt: true, reply: 'Verified. How can I help?' };
101
+ },
102
+ },
103
+ };
104
+ ```
105
+
106
+ ## Errors
107
+
108
+ `PreDirective` shares Directive's construction-time validation. The following
109
+ typed errors may be thrown by `flow.validate(...)` or by the directive bus
110
+ when an invalid PreDirective is emitted:
111
+
112
+ - `FlowConfigurationError` — multiple position fields set (`goTo`, `goToStep`, `complete`, `abort`, `reset`); `reply` co-existing with `abort`; `goTo` set as an empty object.
113
+
114
+ PreDirective-only fields surface no extra construction errors. Two runtime
115
+ behaviors are notable rather than thrown:
116
+
117
+ - Assigning a PreDirective with `appendPrompt`, `injectTools`, or `halt` to
118
+ `session.pendingDirective` causes those fields to be stripped before the
119
+ write (with a debug log). The remaining Directive fields persist normally.
120
+ - Returning a PreDirective from a post-LLM hook (`finalize`, `onComplete`)
121
+ causes the three PreDirective-only fields to be dropped with a debug log;
122
+ the Directive fields are honored.
123
+
124
+ ## Related
125
+
126
+ - [Directives](../concepts/directives.md) — the mental model for the Directive → PreDirective → SignalDirective inheritance chain
127
+ - [Directive](./directive.md) — the parent interface and field semantics for position writes, `reply`, and state writes
128
+ - [Step](./step.md) — `hooks.onEnter` and `hooks.prepare` return `PreDirective`
129
+ - [Flow](./flow.md) — `hooks.onEnter` returns `PreDirective`
130
+ - [Signals](./signals.md) — `SignalDirective` extends `PreDirective` for pre-phase signal firings
131
+ - [Tool](./tool.md) — the type of values in `injectTools[]`