@falai/agent 1.2.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. package/README.md +40 -886
  2. package/dist/adapters/MemoryAdapter.js +2 -2
  3. package/dist/adapters/MemoryAdapter.js.map +1 -1
  4. package/dist/adapters/MongoAdapter.js +2 -2
  5. package/dist/adapters/MongoAdapter.js.map +1 -1
  6. package/dist/adapters/OpenSearchAdapter.d.ts.map +1 -1
  7. package/dist/adapters/OpenSearchAdapter.js +9 -7
  8. package/dist/adapters/OpenSearchAdapter.js.map +1 -1
  9. package/dist/adapters/PostgreSQLAdapter.d.ts +14 -0
  10. package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  11. package/dist/adapters/PostgreSQLAdapter.js +25 -9
  12. package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
  13. package/dist/adapters/PrismaAdapter.js +5 -5
  14. package/dist/adapters/PrismaAdapter.js.map +1 -1
  15. package/dist/adapters/RedisAdapter.js +2 -2
  16. package/dist/adapters/RedisAdapter.js.map +1 -1
  17. package/dist/adapters/SQLiteAdapter.d.ts +17 -0
  18. package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
  19. package/dist/adapters/SQLiteAdapter.js +30 -11
  20. package/dist/adapters/SQLiteAdapter.js.map +1 -1
  21. package/dist/cjs/adapters/MemoryAdapter.js +2 -2
  22. package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
  23. package/dist/cjs/adapters/MongoAdapter.js +2 -2
  24. package/dist/cjs/adapters/MongoAdapter.js.map +1 -1
  25. package/dist/cjs/adapters/OpenSearchAdapter.d.ts.map +1 -1
  26. package/dist/cjs/adapters/OpenSearchAdapter.js +9 -7
  27. package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -1
  28. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts +14 -0
  29. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  30. package/dist/cjs/adapters/PostgreSQLAdapter.js +25 -9
  31. package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
  32. package/dist/cjs/adapters/PrismaAdapter.js +5 -5
  33. package/dist/cjs/adapters/PrismaAdapter.js.map +1 -1
  34. package/dist/cjs/adapters/RedisAdapter.js +2 -2
  35. package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
  36. package/dist/cjs/adapters/SQLiteAdapter.d.ts +17 -0
  37. package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
  38. package/dist/cjs/adapters/SQLiteAdapter.js +30 -11
  39. package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -1
  40. package/dist/cjs/constants/index.d.ts +0 -9
  41. package/dist/cjs/constants/index.d.ts.map +1 -1
  42. package/dist/cjs/constants/index.js +2 -11
  43. package/dist/cjs/constants/index.js.map +1 -1
  44. package/dist/cjs/core/Agent.d.ts +119 -153
  45. package/dist/cjs/core/Agent.d.ts.map +1 -1
  46. package/dist/cjs/core/Agent.js +471 -324
  47. package/dist/cjs/core/Agent.js.map +1 -1
  48. package/dist/cjs/core/AutoChainExecutor.d.ts +107 -0
  49. package/dist/cjs/core/AutoChainExecutor.d.ts.map +1 -0
  50. package/dist/cjs/core/AutoChainExecutor.js +297 -0
  51. package/dist/cjs/core/AutoChainExecutor.js.map +1 -0
  52. package/dist/cjs/core/BranchEvaluator.d.ts +54 -0
  53. package/dist/cjs/core/BranchEvaluator.d.ts.map +1 -0
  54. package/dist/cjs/core/BranchEvaluator.js +130 -0
  55. package/dist/cjs/core/BranchEvaluator.js.map +1 -0
  56. package/dist/cjs/core/DirectiveBus.d.ts +88 -0
  57. package/dist/cjs/core/DirectiveBus.d.ts.map +1 -0
  58. package/dist/cjs/core/DirectiveBus.js +196 -0
  59. package/dist/cjs/core/DirectiveBus.js.map +1 -0
  60. package/dist/cjs/core/DirectiveChainTracker.d.ts +49 -0
  61. package/dist/cjs/core/DirectiveChainTracker.d.ts.map +1 -0
  62. package/dist/cjs/core/DirectiveChainTracker.js +121 -0
  63. package/dist/cjs/core/DirectiveChainTracker.js.map +1 -0
  64. package/dist/cjs/core/Flow.d.ts +186 -0
  65. package/dist/cjs/core/Flow.d.ts.map +1 -0
  66. package/dist/cjs/core/Flow.js +550 -0
  67. package/dist/cjs/core/Flow.js.map +1 -0
  68. package/dist/cjs/core/FlowRouter.d.ts +182 -0
  69. package/dist/cjs/core/FlowRouter.d.ts.map +1 -0
  70. package/dist/cjs/core/{RoutingEngine.js → FlowRouter.js} +323 -306
  71. package/dist/cjs/core/FlowRouter.js.map +1 -0
  72. package/dist/cjs/core/PersistenceManager.d.ts +2 -2
  73. package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
  74. package/dist/cjs/core/PersistenceManager.js +7 -7
  75. package/dist/cjs/core/PersistenceManager.js.map +1 -1
  76. package/dist/cjs/core/PromptComposer.d.ts +21 -8
  77. package/dist/cjs/core/PromptComposer.d.ts.map +1 -1
  78. package/dist/cjs/core/PromptComposer.js +182 -105
  79. package/dist/cjs/core/PromptComposer.js.map +1 -1
  80. package/dist/cjs/core/PromptSectionCache.d.ts +1 -1
  81. package/dist/cjs/core/PromptSectionCache.js +1 -1
  82. package/dist/cjs/core/ResponseEngine.d.ts +18 -8
  83. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
  84. package/dist/cjs/core/ResponseEngine.js +38 -36
  85. package/dist/cjs/core/ResponseEngine.js.map +1 -1
  86. package/dist/cjs/core/ResponseModal.d.ts +73 -56
  87. package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
  88. package/dist/cjs/core/ResponseModal.js +1191 -1014
  89. package/dist/cjs/core/ResponseModal.js.map +1 -1
  90. package/dist/cjs/core/ResponsePipeline.d.ts +124 -26
  91. package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -1
  92. package/dist/cjs/core/ResponsePipeline.js +509 -136
  93. package/dist/cjs/core/ResponsePipeline.js.map +1 -1
  94. package/dist/cjs/core/SignalEvaluator.d.ts +86 -0
  95. package/dist/cjs/core/SignalEvaluator.d.ts.map +1 -0
  96. package/dist/cjs/core/SignalEvaluator.js +333 -0
  97. package/dist/cjs/core/SignalEvaluator.js.map +1 -0
  98. package/dist/cjs/core/SignalProcessor.d.ts +152 -0
  99. package/dist/cjs/core/SignalProcessor.d.ts.map +1 -0
  100. package/dist/cjs/core/SignalProcessor.js +562 -0
  101. package/dist/cjs/core/SignalProcessor.js.map +1 -0
  102. package/dist/cjs/core/Step.d.ts +43 -32
  103. package/dist/cjs/core/Step.d.ts.map +1 -1
  104. package/dist/cjs/core/Step.js +221 -126
  105. package/dist/cjs/core/Step.js.map +1 -1
  106. package/dist/cjs/core/StreamingToolExecutor.d.ts +2 -2
  107. package/dist/cjs/core/StreamingToolExecutor.d.ts.map +1 -1
  108. package/dist/cjs/core/StreamingToolExecutor.js.map +1 -1
  109. package/dist/cjs/core/ToolManager.d.ts +44 -13
  110. package/dist/cjs/core/ToolManager.d.ts.map +1 -1
  111. package/dist/cjs/core/ToolManager.js +174 -91
  112. package/dist/cjs/core/ToolManager.js.map +1 -1
  113. package/dist/cjs/core/createAgent.d.ts +35 -0
  114. package/dist/cjs/core/createAgent.d.ts.map +1 -0
  115. package/dist/cjs/core/createAgent.js +39 -0
  116. package/dist/cjs/core/createAgent.js.map +1 -0
  117. package/dist/cjs/core/flow-namespace.d.ts +49 -0
  118. package/dist/cjs/core/flow-namespace.d.ts.map +1 -0
  119. package/dist/cjs/core/flow-namespace.js +171 -0
  120. package/dist/cjs/core/flow-namespace.js.map +1 -0
  121. package/dist/cjs/index.d.ts +11 -14
  122. package/dist/cjs/index.d.ts.map +1 -1
  123. package/dist/cjs/index.js +18 -22
  124. package/dist/cjs/index.js.map +1 -1
  125. package/dist/cjs/types/agent.d.ts +183 -54
  126. package/dist/cjs/types/agent.d.ts.map +1 -1
  127. package/dist/cjs/types/agent.js +0 -6
  128. package/dist/cjs/types/agent.js.map +1 -1
  129. package/dist/cjs/types/ai.d.ts +3 -3
  130. package/dist/cjs/types/ai.d.ts.map +1 -1
  131. package/dist/cjs/types/errors.d.ts +15 -0
  132. package/dist/cjs/types/errors.d.ts.map +1 -0
  133. package/dist/cjs/types/errors.js +22 -0
  134. package/dist/cjs/types/errors.js.map +1 -0
  135. package/dist/cjs/types/flow.d.ts +513 -0
  136. package/dist/cjs/types/flow.d.ts.map +1 -0
  137. package/dist/cjs/types/{route.js → flow.js} +2 -2
  138. package/dist/cjs/types/flow.js.map +1 -0
  139. package/dist/cjs/types/index.d.ts +7 -6
  140. package/dist/cjs/types/index.d.ts.map +1 -1
  141. package/dist/cjs/types/index.js +6 -2
  142. package/dist/cjs/types/index.js.map +1 -1
  143. package/dist/cjs/types/persistence.d.ts +11 -7
  144. package/dist/cjs/types/persistence.d.ts.map +1 -1
  145. package/dist/cjs/types/routing.d.ts +1 -1
  146. package/dist/cjs/types/routing.d.ts.map +1 -1
  147. package/dist/cjs/types/session.d.ts +24 -23
  148. package/dist/cjs/types/session.d.ts.map +1 -1
  149. package/dist/cjs/types/signals.d.ts +248 -0
  150. package/dist/cjs/types/signals.d.ts.map +1 -0
  151. package/dist/cjs/types/signals.js +11 -0
  152. package/dist/cjs/types/signals.js.map +1 -0
  153. package/dist/cjs/types/template.d.ts +2 -8
  154. package/dist/cjs/types/template.d.ts.map +1 -1
  155. package/dist/cjs/types/tool.d.ts +36 -29
  156. package/dist/cjs/types/tool.d.ts.map +1 -1
  157. package/dist/cjs/types/tool.js +1 -1
  158. package/dist/cjs/types/tool.js.map +1 -1
  159. package/dist/cjs/utils/condition.d.ts +7 -1
  160. package/dist/cjs/utils/condition.d.ts.map +1 -1
  161. package/dist/cjs/utils/condition.js.map +1 -1
  162. package/dist/cjs/utils/id.d.ts +13 -5
  163. package/dist/cjs/utils/id.d.ts.map +1 -1
  164. package/dist/cjs/utils/id.js +24 -10
  165. package/dist/cjs/utils/id.js.map +1 -1
  166. package/dist/cjs/utils/index.d.ts +2 -2
  167. package/dist/cjs/utils/index.d.ts.map +1 -1
  168. package/dist/cjs/utils/index.js +7 -3
  169. package/dist/cjs/utils/index.js.map +1 -1
  170. package/dist/cjs/utils/session.d.ts +44 -5
  171. package/dist/cjs/utils/session.d.ts.map +1 -1
  172. package/dist/cjs/utils/session.js +197 -38
  173. package/dist/cjs/utils/session.js.map +1 -1
  174. package/dist/constants/index.d.ts +0 -9
  175. package/dist/constants/index.d.ts.map +1 -1
  176. package/dist/constants/index.js +3 -9
  177. package/dist/constants/index.js.map +1 -1
  178. package/dist/core/Agent.d.ts +119 -153
  179. package/dist/core/Agent.d.ts.map +1 -1
  180. package/dist/core/Agent.js +472 -325
  181. package/dist/core/Agent.js.map +1 -1
  182. package/dist/core/AutoChainExecutor.d.ts +107 -0
  183. package/dist/core/AutoChainExecutor.d.ts.map +1 -0
  184. package/dist/core/AutoChainExecutor.js +293 -0
  185. package/dist/core/AutoChainExecutor.js.map +1 -0
  186. package/dist/core/BranchEvaluator.d.ts +54 -0
  187. package/dist/core/BranchEvaluator.d.ts.map +1 -0
  188. package/dist/core/BranchEvaluator.js +126 -0
  189. package/dist/core/BranchEvaluator.js.map +1 -0
  190. package/dist/core/DirectiveBus.d.ts +88 -0
  191. package/dist/core/DirectiveBus.d.ts.map +1 -0
  192. package/dist/core/DirectiveBus.js +192 -0
  193. package/dist/core/DirectiveBus.js.map +1 -0
  194. package/dist/core/DirectiveChainTracker.d.ts +49 -0
  195. package/dist/core/DirectiveChainTracker.d.ts.map +1 -0
  196. package/dist/core/DirectiveChainTracker.js +117 -0
  197. package/dist/core/DirectiveChainTracker.js.map +1 -0
  198. package/dist/core/Flow.d.ts +186 -0
  199. package/dist/core/Flow.d.ts.map +1 -0
  200. package/dist/core/Flow.js +546 -0
  201. package/dist/core/Flow.js.map +1 -0
  202. package/dist/core/FlowRouter.d.ts +182 -0
  203. package/dist/core/FlowRouter.d.ts.map +1 -0
  204. package/dist/core/{RoutingEngine.js → FlowRouter.js} +322 -305
  205. package/dist/core/FlowRouter.js.map +1 -0
  206. package/dist/core/PersistenceManager.d.ts +2 -2
  207. package/dist/core/PersistenceManager.d.ts.map +1 -1
  208. package/dist/core/PersistenceManager.js +7 -7
  209. package/dist/core/PersistenceManager.js.map +1 -1
  210. package/dist/core/PromptComposer.d.ts +21 -8
  211. package/dist/core/PromptComposer.d.ts.map +1 -1
  212. package/dist/core/PromptComposer.js +183 -106
  213. package/dist/core/PromptComposer.js.map +1 -1
  214. package/dist/core/PromptSectionCache.d.ts +1 -1
  215. package/dist/core/PromptSectionCache.js +1 -1
  216. package/dist/core/ResponseEngine.d.ts +18 -8
  217. package/dist/core/ResponseEngine.d.ts.map +1 -1
  218. package/dist/core/ResponseEngine.js +38 -36
  219. package/dist/core/ResponseEngine.js.map +1 -1
  220. package/dist/core/ResponseModal.d.ts +73 -56
  221. package/dist/core/ResponseModal.d.ts.map +1 -1
  222. package/dist/core/ResponseModal.js +1193 -1016
  223. package/dist/core/ResponseModal.js.map +1 -1
  224. package/dist/core/ResponsePipeline.d.ts +124 -26
  225. package/dist/core/ResponsePipeline.d.ts.map +1 -1
  226. package/dist/core/ResponsePipeline.js +509 -137
  227. package/dist/core/ResponsePipeline.js.map +1 -1
  228. package/dist/core/SignalEvaluator.d.ts +86 -0
  229. package/dist/core/SignalEvaluator.d.ts.map +1 -0
  230. package/dist/core/SignalEvaluator.js +326 -0
  231. package/dist/core/SignalEvaluator.js.map +1 -0
  232. package/dist/core/SignalProcessor.d.ts +152 -0
  233. package/dist/core/SignalProcessor.d.ts.map +1 -0
  234. package/dist/core/SignalProcessor.js +555 -0
  235. package/dist/core/SignalProcessor.js.map +1 -0
  236. package/dist/core/Step.d.ts +43 -32
  237. package/dist/core/Step.d.ts.map +1 -1
  238. package/dist/core/Step.js +220 -126
  239. package/dist/core/Step.js.map +1 -1
  240. package/dist/core/StreamingToolExecutor.d.ts +2 -2
  241. package/dist/core/StreamingToolExecutor.d.ts.map +1 -1
  242. package/dist/core/StreamingToolExecutor.js.map +1 -1
  243. package/dist/core/ToolManager.d.ts +44 -13
  244. package/dist/core/ToolManager.d.ts.map +1 -1
  245. package/dist/core/ToolManager.js +174 -91
  246. package/dist/core/ToolManager.js.map +1 -1
  247. package/dist/core/createAgent.d.ts +35 -0
  248. package/dist/core/createAgent.d.ts.map +1 -0
  249. package/dist/core/createAgent.js +36 -0
  250. package/dist/core/createAgent.js.map +1 -0
  251. package/dist/core/flow-namespace.d.ts +49 -0
  252. package/dist/core/flow-namespace.d.ts.map +1 -0
  253. package/dist/core/flow-namespace.js +168 -0
  254. package/dist/core/flow-namespace.js.map +1 -0
  255. package/dist/index.d.ts +11 -14
  256. package/dist/index.d.ts.map +1 -1
  257. package/dist/index.js +9 -12
  258. package/dist/index.js.map +1 -1
  259. package/dist/types/agent.d.ts +183 -54
  260. package/dist/types/agent.d.ts.map +1 -1
  261. package/dist/types/agent.js +0 -6
  262. package/dist/types/agent.js.map +1 -1
  263. package/dist/types/ai.d.ts +3 -3
  264. package/dist/types/ai.d.ts.map +1 -1
  265. package/dist/types/errors.d.ts +15 -0
  266. package/dist/types/errors.d.ts.map +1 -0
  267. package/dist/types/errors.js +18 -0
  268. package/dist/types/errors.js.map +1 -0
  269. package/dist/types/flow.d.ts +513 -0
  270. package/dist/types/flow.d.ts.map +1 -0
  271. package/dist/types/flow.js +5 -0
  272. package/dist/types/flow.js.map +1 -0
  273. package/dist/types/index.d.ts +7 -6
  274. package/dist/types/index.d.ts.map +1 -1
  275. package/dist/types/index.js +4 -1
  276. package/dist/types/index.js.map +1 -1
  277. package/dist/types/persistence.d.ts +11 -7
  278. package/dist/types/persistence.d.ts.map +1 -1
  279. package/dist/types/routing.d.ts +1 -1
  280. package/dist/types/routing.d.ts.map +1 -1
  281. package/dist/types/session.d.ts +24 -23
  282. package/dist/types/session.d.ts.map +1 -1
  283. package/dist/types/signals.d.ts +248 -0
  284. package/dist/types/signals.d.ts.map +1 -0
  285. package/dist/types/signals.js +10 -0
  286. package/dist/types/signals.js.map +1 -0
  287. package/dist/types/template.d.ts +2 -8
  288. package/dist/types/template.d.ts.map +1 -1
  289. package/dist/types/tool.d.ts +36 -29
  290. package/dist/types/tool.d.ts.map +1 -1
  291. package/dist/types/tool.js +1 -1
  292. package/dist/types/tool.js.map +1 -1
  293. package/dist/utils/condition.d.ts +7 -1
  294. package/dist/utils/condition.d.ts.map +1 -1
  295. package/dist/utils/condition.js.map +1 -1
  296. package/dist/utils/id.d.ts +13 -5
  297. package/dist/utils/id.d.ts.map +1 -1
  298. package/dist/utils/id.js +22 -9
  299. package/dist/utils/id.js.map +1 -1
  300. package/dist/utils/index.d.ts +2 -2
  301. package/dist/utils/index.d.ts.map +1 -1
  302. package/dist/utils/index.js +2 -2
  303. package/dist/utils/index.js.map +1 -1
  304. package/dist/utils/session.d.ts +44 -5
  305. package/dist/utils/session.d.ts.map +1 -1
  306. package/dist/utils/session.js +193 -37
  307. package/dist/utils/session.js.map +1 -1
  308. package/docs/README.md +15 -202
  309. package/docs/concepts/architecture.md +281 -0
  310. package/docs/concepts/directives.md +400 -0
  311. package/docs/concepts/pipeline.md +399 -0
  312. package/docs/guides/branching.md +263 -0
  313. package/docs/guides/compaction.md +163 -0
  314. package/docs/guides/conditions.md +167 -0
  315. package/docs/guides/error-handling.md +176 -0
  316. package/docs/guides/flow-control.md +409 -0
  317. package/docs/guides/instructions.md +210 -0
  318. package/docs/guides/persistence.md +182 -0
  319. package/docs/guides/streaming.md +137 -0
  320. package/docs/migration/README.md +15 -0
  321. package/docs/migration/route-to-flow.md +560 -0
  322. package/docs/migration/v1-to-v2.md +909 -0
  323. package/docs/reference/adapters.md +481 -0
  324. package/docs/reference/branches.md +241 -0
  325. package/docs/reference/create-agent.md +186 -0
  326. package/docs/reference/directive.md +243 -0
  327. package/docs/reference/errors.md +122 -0
  328. package/docs/reference/flow.md +238 -0
  329. package/docs/reference/instruction.md +177 -0
  330. package/docs/reference/pre-directive.md +131 -0
  331. package/docs/reference/providers.md +227 -0
  332. package/docs/reference/signals.md +356 -0
  333. package/docs/reference/step.md +339 -0
  334. package/docs/reference/tool.md +269 -0
  335. package/docs/start/01-install.md +81 -0
  336. package/docs/start/02-first-agent.md +196 -0
  337. package/docs/start/03-collect-data.md +222 -0
  338. package/docs/start/04-add-tools.md +276 -0
  339. package/docs/start/05-go-to-production.md +216 -0
  340. package/examples/01-quickstart.ts +20 -0
  341. package/examples/02-data-extraction.ts +90 -0
  342. package/examples/03-tools.ts +136 -0
  343. package/examples/04-instructions.ts +100 -0
  344. package/examples/05-branching.ts +140 -0
  345. package/examples/06-flow-control.ts +103 -0
  346. package/examples/07-streaming.ts +69 -0
  347. package/examples/08-persistence.ts +98 -0
  348. package/examples/09-signals.ts +144 -0
  349. package/examples/tsconfig.json +30 -0
  350. package/package.json +2 -1
  351. package/src/adapters/MemoryAdapter.ts +3 -3
  352. package/src/adapters/MongoAdapter.ts +3 -3
  353. package/src/adapters/OpenSearchAdapter.ts +10 -8
  354. package/src/adapters/PostgreSQLAdapter.ts +26 -10
  355. package/src/adapters/PrismaAdapter.ts +6 -6
  356. package/src/adapters/RedisAdapter.ts +3 -3
  357. package/src/adapters/SQLiteAdapter.ts +31 -12
  358. package/src/constants/index.ts +2 -10
  359. package/src/core/Agent.ts +585 -374
  360. package/src/core/AutoChainExecutor.ts +440 -0
  361. package/src/core/BranchEvaluator.ts +167 -0
  362. package/src/core/DirectiveBus.ts +248 -0
  363. package/src/core/DirectiveChainTracker.ts +144 -0
  364. package/src/core/Flow.ts +666 -0
  365. package/src/core/{RoutingEngine.ts → FlowRouter.ts} +385 -365
  366. package/src/core/PersistenceManager.ts +8 -8
  367. package/src/core/PromptComposer.ts +209 -140
  368. package/src/core/PromptSectionCache.ts +1 -1
  369. package/src/core/ResponseEngine.ts +61 -46
  370. package/src/core/ResponseModal.ts +1453 -1240
  371. package/src/core/ResponsePipeline.ts +655 -175
  372. package/src/core/SignalEvaluator.ts +420 -0
  373. package/src/core/SignalProcessor.ts +723 -0
  374. package/src/core/Step.ts +279 -176
  375. package/src/core/StreamingToolExecutor.ts +4 -4
  376. package/src/core/ToolManager.ts +200 -97
  377. package/src/core/createAgent.ts +40 -0
  378. package/src/core/flow-namespace.ts +219 -0
  379. package/src/index.ts +42 -36
  380. package/src/types/agent.ts +182 -53
  381. package/src/types/ai.ts +3 -3
  382. package/src/types/errors.ts +18 -0
  383. package/src/types/flow.ts +590 -0
  384. package/src/types/index.ts +43 -16
  385. package/src/types/persistence.ts +12 -8
  386. package/src/types/routing.ts +1 -1
  387. package/src/types/session.ts +26 -23
  388. package/src/types/signals.ts +321 -0
  389. package/src/types/template.ts +3 -11
  390. package/src/types/tool.ts +50 -42
  391. package/src/utils/condition.ts +13 -4
  392. package/src/utils/id.ts +27 -9
  393. package/src/utils/index.ts +6 -2
  394. package/src/utils/session.ts +238 -42
  395. package/dist/cjs/core/BatchExecutor.d.ts +0 -359
  396. package/dist/cjs/core/BatchExecutor.d.ts.map +0 -1
  397. package/dist/cjs/core/BatchExecutor.js +0 -861
  398. package/dist/cjs/core/BatchExecutor.js.map +0 -1
  399. package/dist/cjs/core/BatchPromptBuilder.d.ts +0 -89
  400. package/dist/cjs/core/BatchPromptBuilder.d.ts.map +0 -1
  401. package/dist/cjs/core/BatchPromptBuilder.js +0 -223
  402. package/dist/cjs/core/BatchPromptBuilder.js.map +0 -1
  403. package/dist/cjs/core/Route.d.ts +0 -180
  404. package/dist/cjs/core/Route.d.ts.map +0 -1
  405. package/dist/cjs/core/Route.js +0 -542
  406. package/dist/cjs/core/Route.js.map +0 -1
  407. package/dist/cjs/core/RoutingEngine.d.ts +0 -185
  408. package/dist/cjs/core/RoutingEngine.d.ts.map +0 -1
  409. package/dist/cjs/core/RoutingEngine.js.map +0 -1
  410. package/dist/cjs/types/route.d.ts +0 -336
  411. package/dist/cjs/types/route.d.ts.map +0 -1
  412. package/dist/cjs/types/route.js.map +0 -1
  413. package/dist/core/BatchExecutor.d.ts +0 -359
  414. package/dist/core/BatchExecutor.d.ts.map +0 -1
  415. package/dist/core/BatchExecutor.js +0 -856
  416. package/dist/core/BatchExecutor.js.map +0 -1
  417. package/dist/core/BatchPromptBuilder.d.ts +0 -89
  418. package/dist/core/BatchPromptBuilder.d.ts.map +0 -1
  419. package/dist/core/BatchPromptBuilder.js +0 -219
  420. package/dist/core/BatchPromptBuilder.js.map +0 -1
  421. package/dist/core/Route.d.ts +0 -180
  422. package/dist/core/Route.d.ts.map +0 -1
  423. package/dist/core/Route.js +0 -538
  424. package/dist/core/Route.js.map +0 -1
  425. package/dist/core/RoutingEngine.d.ts +0 -185
  426. package/dist/core/RoutingEngine.d.ts.map +0 -1
  427. package/dist/core/RoutingEngine.js.map +0 -1
  428. package/dist/types/route.d.ts +0 -336
  429. package/dist/types/route.d.ts.map +0 -1
  430. package/dist/types/route.js +0 -5
  431. package/dist/types/route.js.map +0 -1
  432. package/docs/CONTRIBUTING.md +0 -521
  433. package/docs/api/README.md +0 -3299
  434. package/docs/api/overview.md +0 -1410
  435. package/docs/architecture/data-extraction-flow.md +0 -360
  436. package/docs/architecture/multi-step-execution.md +0 -277
  437. package/docs/core/agent/README.md +0 -938
  438. package/docs/core/agent/context-management.md +0 -796
  439. package/docs/core/agent/rules-and-prohibitions.md +0 -113
  440. package/docs/core/agent/session-management.md +0 -693
  441. package/docs/core/ai-integration/prompt-composition.md +0 -355
  442. package/docs/core/ai-integration/providers.md +0 -515
  443. package/docs/core/ai-integration/response-processing.md +0 -433
  444. package/docs/core/conversation-flows/data-collection.md +0 -772
  445. package/docs/core/conversation-flows/route-dsl.md +0 -509
  446. package/docs/core/conversation-flows/routes.md +0 -249
  447. package/docs/core/conversation-flows/step-transitions.md +0 -731
  448. package/docs/core/conversation-flows/steps.md +0 -268
  449. package/docs/core/error-handling.md +0 -830
  450. package/docs/core/persistence/adapters.md +0 -255
  451. package/docs/core/persistence/session-storage.md +0 -656
  452. package/docs/core/routing/intelligent-routing.md +0 -470
  453. package/docs/core/tools/enhanced-tool.md +0 -186
  454. package/docs/core/tools/streaming-execution.md +0 -161
  455. package/docs/core/tools/tool-definition.md +0 -970
  456. package/docs/core/tools/tool-scoping.md +0 -819
  457. package/docs/guides/advanced-patterns/publishing.md +0 -186
  458. package/docs/guides/context-compaction.md +0 -96
  459. package/docs/guides/error-handling-patterns.md +0 -578
  460. package/docs/guides/getting-started/README.md +0 -795
  461. package/docs/guides/migration/README.md +0 -101
  462. package/docs/guides/migration/flexible-routing-conditions.md +0 -375
  463. package/docs/guides/migration/multi-step-execution.md +0 -393
  464. package/docs/guides/migration/response-modal-refactor.md +0 -518
  465. package/docs/guides/prompt-optimization.md +0 -164
  466. package/examples/advanced-patterns/context-compaction.ts +0 -223
  467. package/examples/advanced-patterns/knowledge-based-agent.ts +0 -735
  468. package/examples/advanced-patterns/persistent-onboarding.ts +0 -728
  469. package/examples/advanced-patterns/route-lifecycle-hooks.ts +0 -556
  470. package/examples/advanced-patterns/streaming-responses.ts +0 -656
  471. package/examples/ai-providers/anthropic-integration.ts +0 -388
  472. package/examples/ai-providers/openai-integration.ts +0 -228
  473. package/examples/condition-patterns/function-only-conditions.ts +0 -365
  474. package/examples/condition-patterns/mixed-array-conditions.ts +0 -477
  475. package/examples/condition-patterns/route-skipif-patterns.ts +0 -468
  476. package/examples/condition-patterns/step-skipif-patterns.ts +0 -0
  477. package/examples/condition-patterns/string-only-conditions.ts +0 -296
  478. package/examples/conversation-flows/completion-transitions.ts +0 -318
  479. package/examples/core-concepts/basic-agent.ts +0 -503
  480. package/examples/core-concepts/modern-streaming-api.ts +0 -309
  481. package/examples/core-concepts/schema-driven-extraction.ts +0 -332
  482. package/examples/core-concepts/session-management.ts +0 -494
  483. package/examples/integrations/database-integration.ts +0 -631
  484. package/examples/integrations/healthcare-integration.ts +0 -595
  485. package/examples/integrations/search-integration.ts +0 -530
  486. package/examples/integrations/server-session-management.ts +0 -307
  487. package/examples/persistence/custom-adapter.ts +0 -526
  488. package/examples/persistence/database-persistence.ts +0 -583
  489. package/examples/persistence/memory-sessions.ts +0 -495
  490. package/examples/persistence/prisma-schema.example.prisma +0 -74
  491. package/examples/persistence/redis-persistence.ts +0 -488
  492. package/examples/tools/basic-tools.ts +0 -765
  493. package/examples/tools/data-enrichment-tools.ts +0 -593
  494. package/examples/tools/enhanced-tool-metadata.ts +0 -268
  495. package/examples/tools/streaming-tool-execution.ts +0 -283
  496. package/src/core/BatchExecutor.ts +0 -1187
  497. package/src/core/BatchPromptBuilder.ts +0 -299
  498. package/src/core/Route.ts +0 -678
  499. package/src/types/route.ts +0 -392
@@ -0,0 +1,400 @@
1
+ ---
2
+ title: "Directives"
3
+ description: "The flat object shape any tool, hook, or branch returns to write state, redirect the conversation, or speak verbatim."
4
+ type: concept
5
+ order: 3
6
+ ---
7
+
8
+ # Directives
9
+
10
+ > **Where this is introduced:** [Turn pipeline](./pipeline.md)
11
+
12
+ A directive is the single language `@falai/agent` speaks for control
13
+ flow. When a tool decides "this user is ineligible," it returns
14
+ `{ goTo: "Denial", reply: "Sorry — you don't qualify." }`. When a
15
+ finalize hook closes a booking, it returns
16
+ `{ complete: true, dataUpdate: { bookingId } }`. When a pre-phase
17
+ signal detects a frustrated user, it dispatches
18
+ `{ appendPrompt: ["Lead with empathy."] }`. Different jobs, different
19
+ emitters, one shape.
20
+
21
+ This page explains why the shape is flat, what each field does, how
22
+ they merge when more than one handler emits during the same turn, and
23
+ how `Directive`, `PreDirective`, and `SignalDirective` form the
24
+ inheritance chain that lets pre-LLM hooks and signals add capability
25
+ without adding a parallel type system. The page is conceptual — the
26
+ [directive reference](../reference/directive.md) carries the
27
+ field-by-field contract.
28
+
29
+ ## Why a flat shape
30
+
31
+ An earlier draft of v2 modeled directives as a discriminated union:
32
+ `{ type: 'goto_flow', flow: 'X' }`, `{ type: 'complete', next: ... }`,
33
+ `{ type: 'abort', reason: ... }`, and so on. The shape that ships is
34
+ flat — a single interface with optional fields, no `type`
35
+ discriminator, no builder, no factory functions. Four reasons drove
36
+ the decision, and each one is visible at the call site once you know
37
+ to look for it.
38
+
39
+ **Single shape.** Every emitter returns the same object literal. A
40
+ finalize hook does not have to choose between `Directive.goto({...})`
41
+ and `Directive.complete({...})` and `Directive.reply({...})` — it
42
+ returns `{}` with whichever fields it needs. Authors learn one shape
43
+ and reach for it from tools, from prepare hooks, from finalize hooks,
44
+ from signal handlers, from branch `then` targets. The framework's
45
+ control-flow vocabulary is one type wide. The same object literal is
46
+ also persistable verbatim as `session.pendingDirective`, so the shape
47
+ that sits in source code is the same shape that crosses the
48
+ persistence boundary.
49
+
50
+ **Trivially mergeable.** Algorithm 4 — the per-turn merge that the
51
+ pipeline runs over the directive bus — works on a flat object: pick
52
+ the winning position field by precedence, last-wins for `reply`,
53
+ shallow-merge state writes, concatenate the pre-LLM arrays. A nested
54
+ discriminated union would force a per-variant merge case at every
55
+ combinator: how do you merge a `goto_flow` with a `complete`? With a
56
+ `reply`? With a `dataUpdate`? Every cross-variant combination becomes
57
+ its own special case. With a flat object, "merge" is one function
58
+ that does not branch on shape.
59
+
60
+ **Validates statically.** TypeScript narrowing on field presence is
61
+ clean. `if (d.goTo) { /* d.goTo is string | object */ }` is the
62
+ entire pattern. A discriminated union adds one extra branching level
63
+ at every call site — `if (d.type === 'goto_flow') { /* d is the
64
+ goto_flow variant */ }` — and the variant types repeat the same
65
+ optional-fields prose for state writes and `reply`. The flat shape
66
+ moves "is this a position directive or a state directive or a reply"
67
+ from a type-level question to a runtime question that the merge
68
+ algorithm answers once.
69
+
70
+ **Composable.** A directive carries up to four orthogonal payloads
71
+ without forcing them into a hierarchy: at most one position field,
72
+ optional state writes (`dataUpdate` / `contextUpdate`), an optional
73
+ verbatim `reply`, and on `PreDirective` an optional set of pre-LLM
74
+ augmentations. `dataUpdate` works alongside `goTo`. `reply` works
75
+ alongside `complete`. A booking tool's success result writes the
76
+ booking id and finishes the flow in one return value:
77
+ `{ complete: true, dataUpdate: { bookingId } }`. A bridge utterance
78
+ at a flow boundary writes nothing and only speaks: `{ reply: "Let me
79
+ transfer you." }`. The same primitive covers both because the fields
80
+ do not exclude each other by shape — only by validation.
81
+
82
+ The trade-off is that exhaustive `case` checking on a `type`
83
+ discriminator is gone. The pipeline replaces it with structural
84
+ validation (`flow.validate`) — one position field at most, no empty
85
+ `goTo: {}`, no `reply` alongside `abort` — that runs at apply time
86
+ anyway, since flow and step lookups are runtime checks regardless. The
87
+ exchange is one less compile-time check for a far cleaner authoring
88
+ surface and a merge algorithm that does not branch on shape.
89
+
90
+ ## Position fields and their precedence
91
+
92
+ A directive carries at most one **position field**. Position fields
93
+ answer the question "where does the conversation go next?" The five
94
+ options span every form of position control the framework offers:
95
+
96
+ | Field | What it means |
97
+ |-------|---------------|
98
+ | `goTo` | Jump to another flow. |
99
+ | `goToStep` | Jump to a step (within the current flow, or — in the object form — within another flow). |
100
+ | `complete` | Mark the current flow done. The flow's completion logic runs. |
101
+ | `abort` | End the conversation. Optionally clear the session. |
102
+ | `reset` | Restart the current flow. Optionally clear its declared fields. |
103
+
104
+ Each of `goTo`, `goToStep`, `complete`, `abort`, and `reset` accepts
105
+ both a shorthand and an object form. The shorthand expresses the
106
+ common case (`goTo: "Booking"`, `complete: true`, `abort: "denied"`).
107
+ The object form exposes the optional knobs — `reason` strings for
108
+ observability, `data` for pre-entry state writes, `clearSession` /
109
+ `clearData` flags for the destructive variants. The fields are
110
+ mutually exclusive: setting two at once throws
111
+ `FlowConfigurationError` at validation. There is no "go to *and*
112
+ abort" — only one position can win per directive.
113
+
114
+ When more than one emitter writes a position field during the same
115
+ turn — a tool returns `goTo` and a finalize hook returns `complete` —
116
+ the merge algorithm picks one winner by precedence:
117
+
118
+ ```
119
+ abort > complete > goTo / goToStep > reset
120
+ ```
121
+
122
+ The order encodes intent. **`abort` always wins.** A handler that
123
+ ended the conversation cannot be overridden by a later "go somewhere
124
+ else" — there is no somewhere else. **`complete` beats `goTo` and
125
+ `goToStep`.** The flow is ending; any follow-up jump belongs in
126
+ `complete.next` (which chains another directive after completion),
127
+ not as a competing position field. **`goTo` and `goToStep` share a
128
+ tier.** Both express "next position is here" — the difference is
129
+ flow-level vs step-level granularity, and within the tier last
130
+ emission wins. **`reset` is lowest.** Any explicit jump out of the
131
+ current flow beats a "restart this flow" emitted earlier in the
132
+ phase.
133
+
134
+ Within the same tier, the most recent emission wins, with a debug
135
+ log naming all losers so a noisy turn is diagnosable from the trace.
136
+ The precedence ordering does not change between phases: it applies to
137
+ the pre-LLM bus, the post-LLM bus, and the signal phases identically.
138
+
139
+ ## State writes
140
+
141
+ Two fields — `dataUpdate` and `contextUpdate` — write to session
142
+ state. Both are `Partial<>` slices of their respective surfaces:
143
+ `dataUpdate?: Partial<TData>` writes into `session.data`,
144
+ `contextUpdate?: Partial<TContext>` writes into `session.context`.
145
+ Both fire their respective hooks (`flow.hooks.onDataUpdate`,
146
+ `flow.hooks.onContextUpdate`) after the merge applies, and both run
147
+ through schema validation atomically — every field across every
148
+ emitter on this turn is checked together, and the session is not
149
+ mutated unless the whole set passes.
150
+
151
+ State writes are **additive** and shallow-merged across emitters in
152
+ emission order. If a flow-level `onEnter` writes
153
+ `{ dataUpdate: { tier: "vip" } }` and a step-level `prepare` writes
154
+ `{ dataUpdate: { lastSeen: now } }`, the merged result is
155
+ `{ tier: "vip", lastSeen: now }` — neither hook needs to know about
156
+ the other. On key collision, last write wins. The merge is shallow —
157
+ top-level keys are replaced wholesale, nested objects are not
158
+ deep-merged. To update a nested object, read it from `data`, merge
159
+ in code, write back the full sub-object. Deep merge is intentionally
160
+ absent because it would silently disagree with TypeScript's
161
+ `Partial<>` shape: the type says "I'm overwriting this key," and the
162
+ runtime should agree.
163
+
164
+ State writes always apply, regardless of what the position fields do.
165
+ A directive with `{ goTo: "Denial", dataUpdate: { reason: "expired" }
166
+ }` jumps flows *and* writes the reason. A directive with only
167
+ `{ dataUpdate: {...} }` writes state and stays where it is. Position
168
+ fields and state writes are orthogonal payloads; they don't compete
169
+ for the same slot.
170
+
171
+ ## Reply as a verbatim utterance
172
+
173
+ The `reply: string` field is the framework's way of letting code
174
+ speak. When a directive sets `reply`, the LLM call for the entered
175
+ step is skipped this turn and the literal string becomes the
176
+ assistant's message. The text is taken verbatim — no templating, no
177
+ post-processing, no "the model rephrased it" surprise.
178
+
179
+ `reply` is the right tool for utterances that should be exact:
180
+ confirmations ("Booking confirmed."), bridges ("Connecting you with a
181
+ specialist now."), refusals ("Sorry — you don't qualify."), and
182
+ boilerplate at flow boundaries. It is the wrong tool for anything
183
+ that should adapt to context — that's what the model is for. The two
184
+ shapes coexist on the same step boundary: `reply` for the line, the
185
+ LLM for the conversation.
186
+
187
+ `reply` co-validates with two other fields. With **`abort`**, it is
188
+ rejected at validation — an aborted conversation cannot deliver a
189
+ reply. With **`halt: true`** (a `PreDirective` field, see below), it
190
+ is the assistant message and the turn ends with
191
+ `stoppedReason: 'reply'`; if `halt` is set without `reply`, the turn
192
+ ends with `stoppedReason: 'halt'` and an empty body. Across multiple
193
+ emitters in the same turn, `reply` is **last-wins** — the most
194
+ recent emission overrides earlier ones, with a debug log so the
195
+ override is visible in the trace.
196
+
197
+ `reply` is the same shape on `Directive` and on `PreDirective` —
198
+ there is no separate "speak before the LLM" vs "speak after the
199
+ LLM" type. The phase the directive runs in determines whether the
200
+ reply replaces a message that would have been generated (pre-LLM) or
201
+ replaces one that just was (post-LLM). The field stays the same.
202
+
203
+ ## PreDirective fields
204
+
205
+ `PreDirective` is the `Directive` variant that pre-LLM hooks return.
206
+ It inherits every base field — position writes, state writes,
207
+ `reply` — and adds three more that only make sense before this turn's
208
+ LLM call: `appendPrompt`, `injectTools`, and `halt`.
209
+
210
+ **`appendPrompt: string[]`** is the prompt nudge slot. Each string is
211
+ a sentence the prompt composer appends to the system prompt for this
212
+ turn only. A flow-level `onEnter` that detects a VIP caller can add
213
+ "This caller is a VIP — confirm preferences before suggesting
214
+ options." A step-level `prepare` that detects a returning customer
215
+ can add "The user is a returning customer; skip introductions." Both
216
+ fire on the same turn, and both sentences land in the prompt's
217
+ per-turn appendage slot in emission order. The slot is never cached
218
+ (the prompt section cache memoizes static sections only) and never
219
+ persisted — `appendPrompt` lives for one turn and is gone.
220
+
221
+ **`injectTools: Tool[]`** is the per-turn tool slot. Tools listed
222
+ here are added to the available tool list for this turn only,
223
+ stacked on top of the agent → flow → step → transient resolution
224
+ chain. A `prepare` hook that detects an ambiguous request can inject
225
+ a `lookup_account` tool for a single LLM call without registering it
226
+ on the step or the flow. The slot is never persisted — tool
227
+ references are functions, and functions are not JSON-serializable —
228
+ so the field is structurally one-turn-only.
229
+
230
+ **`halt: boolean`** is the kill switch. When any pre-phase emitter
231
+ sets `halt: true`, the LLM call is skipped entirely. If `reply` is
232
+ also set, the verbatim string becomes the assistant message. If not,
233
+ the turn ends with `stoppedReason: 'halt'` and an empty body. `halt`
234
+ merges by **logical-OR** — a single emitter setting it is enough to
235
+ halt the turn. The field is the framework's circuit breaker: a hook
236
+ that detects an unresolvable state can stop the turn outright
237
+ without competing with other emitters.
238
+
239
+ The three `PreDirective`-only fields are stripped from
240
+ `session.pendingDirective` before persistence — `pendingDirective`
241
+ holds a plain `Directive`, and the augmentation fields cannot survive
242
+ across turns by design. If a post-LLM hook returns a `PreDirective`
243
+ with these fields set, they are dropped with a debug warning: an
244
+ `appendPrompt` after the fact has no prompt to append to, an
245
+ `injectTools` after the fact has no LLM call to inject into, and a
246
+ `halt` after the fact has no LLM call to halt. The remaining base
247
+ `Directive` portion is honored.
248
+
249
+ `appendPrompt` is concatenated across emitters in emission order
250
+ without deduplication — duplicate sentences from different sources
251
+ are preserved (a flow-level "be polite" plus a step-level "be polite"
252
+ is acceptable redundancy). `injectTools` is concatenated and then
253
+ deduped by `Tool.id`, with the later definition winning — typically a
254
+ step-level injection overriding a flow-level default. `halt` is
255
+ logical-OR. The merge rules for the inherited base fields stay
256
+ identical: position fields by precedence, `reply` last-wins, state
257
+ writes shallow-merged.
258
+
259
+ ## The inheritance chain
260
+
261
+ `Directive` is the base. `PreDirective` extends it with the three
262
+ pre-LLM-only fields. `SignalDirective` extends `PreDirective` further
263
+ with two signal-specific fields. The chain is one direction —
264
+ capabilities accumulate as you go down — and each level is the return
265
+ type of a specific class of emitter:
266
+
267
+ ```mermaid
268
+ classDiagram
269
+ Directive <|-- PreDirective
270
+ PreDirective <|-- SignalDirective
271
+
272
+ class Directive {
273
+ +goTo? string | object
274
+ +goToStep? string | object
275
+ +complete? true | object
276
+ +abort? string | object
277
+ +reset? true | object
278
+ +reply? string
279
+ +dataUpdate? Partial~TData~
280
+ +contextUpdate? Partial~TContext~
281
+ }
282
+
283
+ class PreDirective {
284
+ +appendPrompt? string[]
285
+ +injectTools? Tool[]
286
+ +halt? boolean
287
+ }
288
+
289
+ class SignalDirective {
290
+ +stopOtherSignals? boolean
291
+ +replyWith? string | function
292
+ }
293
+
294
+ note for Directive "Returned by tools, finalize hooks, branches.\nPersistable as session.pendingDirective."
295
+ note for PreDirective "Returned by prepare hooks, onEnter hooks.\nTransient — one-turn lifetime."
296
+ note for SignalDirective "Returned by signals (pre / post / both phases)."
297
+ ```
298
+
299
+ `Directive` is what tools (return value or `ctx.dispatch`), `finalize`
300
+ hooks, `flow.hooks.onComplete`, and branch `then` targets return. It
301
+ is plain JSON-serializable data — the same shape that sits on the
302
+ session as `pendingDirective` and crosses the persistence boundary.
303
+
304
+ `PreDirective` is what `flow.hooks.onEnter`, `step.hooks.onEnter`,
305
+ and `step.hooks.prepare` return. The three augmentation fields and a
306
+ live `Tool[]` reference make it non-serializable; the type system
307
+ encodes the one-turn lifetime by being a structurally separate type
308
+ that the engine strips before persistence.
309
+
310
+ `SignalDirective` is what signal handlers return — pre-phase
311
+ handlers, post-phase handlers, and `both`-phase handlers all use the
312
+ same type. The two added fields are signal-pipeline-specific:
313
+ `stopOtherSignals` skips remaining handlers in the same phase (it is
314
+ consumed inside the signal pipeline, not the directive bus), and
315
+ `replyWith` is a late-binding `reply` that accepts a function form
316
+ evaluated at emit time. Phase semantics still apply: when a
317
+ `SignalDirective` runs in the post-phase, the inherited `appendPrompt`
318
+ / `injectTools` / `halt` fields are dropped (they have no meaning
319
+ after the LLM call) and inherited position fields set
320
+ `pendingDirective` for the *next* turn rather than redirecting this
321
+ one.
322
+
323
+ The three types share one merge algorithm and one validation pass.
324
+ A pre-phase signal can dispatch a `SignalDirective`, a `prepare` hook
325
+ can return a `PreDirective`, and the engine merges them through the
326
+ same `flow.merge` that handles tool directives — the inheritance
327
+ chain exists to widen the type at the call site without splitting the
328
+ runtime.
329
+
330
+ ## The `flow` namespace
331
+
332
+ There are no constructor builders for directives. Directives are
333
+ plain object literals — that is the whole point of the flat shape.
334
+ What the framework does export is a small runtime helper namespace
335
+ for working with directives in code: validating shapes that arrived
336
+ from outside the framework, merging two directives by hand, and
337
+ narrowing `unknown` values in type guards.
338
+
339
+ ```typescript
340
+ import { flow } from "@falai/agent";
341
+
342
+ flow.isDirective(x); // structural type guard
343
+ flow.merge(a, b); // Algorithm 4 merge of two directives
344
+ flow.validate(d); // throws FlowConfigurationError on invalid shape
345
+ ```
346
+
347
+ `flow.isDirective(x)` is a structural type guard. It returns `true`
348
+ for any non-null, non-array object — primitives, `null`, `undefined`,
349
+ arrays, and functions are filtered out. Use it to narrow an `unknown`
350
+ value coming off an RPC payload or a queue message before passing it
351
+ to `applyDirective` or `agent.dispatch`.
352
+
353
+ `flow.merge(a, b)` is the same Algorithm 4 the engine runs internally
354
+ on the per-turn directive bus, exposed for callers that need to
355
+ compose results before dispatching them. Position fields merge by
356
+ precedence (`abort > complete > goTo / goToStep > reset`, last-wins
357
+ within the same tier), `reply` is last-wins, `dataUpdate` and
358
+ `contextUpdate` shallow-merge in emission order, `appendPrompt`
359
+ concatenates without deduplication, `injectTools` concatenates and
360
+ then dedupes by `Tool.id` (later definition wins), and `halt` is
361
+ logical-OR. The function is generic in the shared subtype: merging
362
+ two `PreDirective`s yields a `PreDirective`, merging two plain
363
+ `Directive`s yields a `Directive`.
364
+
365
+ `flow.validate(d)` enforces three structural invariants and throws
366
+ `FlowConfigurationError` when any fails: at most one position field
367
+ per directive, no empty `goTo: {}` (the object form requires a flow
368
+ id), no `reply` alongside `abort`. The pipeline calls it eagerly on
369
+ every emitted directive, so downstream code can rely on shape. It
370
+ does **not** validate that referenced flows or steps exist — that
371
+ check happens at apply time, against the agent's flow registry, which
372
+ the validator does not have a handle on.
373
+
374
+ The namespace's design intent is "runtime helpers, not authoring
375
+ sugar." If you're constructing a directive in source, write the
376
+ object literal. If you're handling a directive that came from
377
+ elsewhere, narrow it with `flow.isDirective`, validate it with
378
+ `flow.validate`, and merge it with `flow.merge`. The seam between
379
+ "control flow as code" and "control flow as data" is exactly that
380
+ small.
381
+
382
+ ## Where to go next
383
+
384
+ The directive's mental model is in this page; the field-by-field
385
+ contract — every position field's shorthand and object form, every
386
+ state-write rule, every typed error the validator can throw — is in
387
+ the [Directive reference](../reference/directive.md). The pre-LLM
388
+ extras have their own [PreDirective reference](../reference/pre-directive.md).
389
+ The signal-specific additions live in [Signals](../reference/signals.md).
390
+
391
+ When the goal is to *use* directives in handlers, the
392
+ [Flow control guide](../guides/flow-control.md) walks through the
393
+ recipes: redirecting from a tool, completing a flow with a chained
394
+ follow-up, aborting on a permission failure, replying verbatim from a
395
+ finalize hook, dispatching a directive from outside a turn. When the
396
+ goal is to *understand* where directives sit in the per-turn
397
+ sequence, [Turn pipeline](./pipeline.md) covers the bus, the merge
398
+ phases, and the resolution precedence around the directive surface.
399
+
400
+ **Next:** [createAgent reference](../reference/create-agent.md)