@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,227 @@
1
+ ---
2
+ title: "Providers"
3
+ description: "Strategy classes that connect an Agent to Gemini, OpenAI, Anthropic, or OpenRouter."
4
+ type: reference
5
+ order: 10
6
+ ---
7
+
8
+ # Providers
9
+
10
+ > **Where this is introduced:** [Install](../start/01-install.md)
11
+
12
+ Providers are the strategy plug between an `Agent` and a model vendor. Every provider implements the same `AiProvider` interface, so the Agent itself stays vendor-agnostic. Pass an instance to `createAgent({ provider })` and the agent talks to that vendor for every turn (and for compaction, if you wire it in).
13
+
14
+ `@falai/agent` ships four built-in providers. All four accept an `apiKey` and a required `model`, support `backupModels` for automatic failover on overload or 5xx, and accept a vendor-typed `config` object that flows through to the underlying SDK.
15
+
16
+ | Provider | Class | Options | SDK |
17
+ |----------|-------|---------|-----|
18
+ | Google Gemini | `GeminiProvider` | `GeminiProviderOptions` | `@google/genai` |
19
+ | OpenAI | `OpenAIProvider` | `OpenAIProviderOptions` | `openai` |
20
+ | Anthropic Claude | `AnthropicProvider` | `AnthropicProviderOptions` | `@anthropic-ai/sdk` |
21
+ | OpenRouter | `OpenRouterProvider` | `OpenRouterProviderOptions` | `openai` (compat) |
22
+
23
+ ## Use with createAgent
24
+
25
+ `createAgent({ provider })` accepts any class that implements `AiProvider`. Swap providers by changing the constructor; nothing else in your agent has to move.
26
+
27
+ ```typescript
28
+ import {
29
+ createAgent,
30
+ GeminiProvider,
31
+ OpenAIProvider,
32
+ AnthropicProvider,
33
+ OpenRouterProvider,
34
+ } from "@falai/agent";
35
+
36
+ const provider =
37
+ process.env.PROVIDER === "openai"
38
+ ? new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY!, model: "gpt-5-mini" })
39
+ : process.env.PROVIDER === "anthropic"
40
+ ? new AnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY!, model: "claude-sonnet-4-5" })
41
+ : process.env.PROVIDER === "openrouter"
42
+ ? new OpenRouterProvider({ apiKey: process.env.OPENROUTER_API_KEY!, model: "anthropic/claude-sonnet-4.5" })
43
+ : new GeminiProvider({ apiKey: process.env.GEMINI_API_KEY!, model: "models/gemini-2.5-pro" });
44
+
45
+ const agent = createAgent({ provider, schema, flows });
46
+ ```
47
+
48
+ ## GeminiProvider
49
+
50
+ ### Signature
51
+
52
+ ```typescript
53
+ new GeminiProvider(options: GeminiProviderOptions)
54
+
55
+ interface GeminiProviderOptions {
56
+ apiKey: string;
57
+ model: string;
58
+ backupModels?: string[];
59
+ config?: Partial<GenerateContentConfig>; // from @google/genai
60
+ retryConfig?: { timeout?: number; retries?: number };
61
+ }
62
+ ```
63
+
64
+ ### Fields
65
+
66
+ | Field | Type | Required | Default | Notes |
67
+ |-------|------|----------|---------|-------|
68
+ | `apiKey` | `string` | yes | — | Throws if empty. |
69
+ | `model` | `string` | yes | — | Use the fully-qualified id, e.g. `"models/gemini-2.5-pro"`. |
70
+ | `backupModels` | `string[]` | no | `[]` | Tried in order on 429/500/503/overload errors. |
71
+ | `config` | `Partial<GenerateContentConfig>` | no | — | Vendor-typed defaults (e.g. `temperature`, `systemInstruction`). |
72
+ | `retryConfig.timeout` | `number` | no | `60000` | Per-attempt timeout in ms. |
73
+ | `retryConfig.retries` | `number` | no | `3` | Total attempts before giving up. |
74
+
75
+ ### Example
76
+
77
+ ```typescript
78
+ const gemini = new GeminiProvider({
79
+ apiKey: process.env.GEMINI_API_KEY!,
80
+ model: "models/gemini-2.5-pro",
81
+ backupModels: ["models/gemini-2.5-flash"],
82
+ config: { temperature: 0.3 },
83
+ });
84
+ ```
85
+
86
+ ## OpenAIProvider
87
+
88
+ ### Signature
89
+
90
+ ```typescript
91
+ new OpenAIProvider(options: OpenAIProviderOptions)
92
+
93
+ interface OpenAIProviderOptions {
94
+ apiKey: string;
95
+ organization?: string;
96
+ model: string;
97
+ backupModels?: string[];
98
+ config?: Partial<Omit<ChatCompletionCreateParamsNonStreaming, "model" | "messages">>;
99
+ retryConfig?: { timeout?: number; retries?: number };
100
+ }
101
+ ```
102
+
103
+ ### Fields
104
+
105
+ | Field | Type | Required | Default | Notes |
106
+ |-------|------|----------|---------|-------|
107
+ | `apiKey` | `string` | yes | — | Throws if empty. |
108
+ | `organization` | `string` | no | — | Forwarded as `OpenAI-Organization`. |
109
+ | `model` | `string` | yes | — | e.g. `"gpt-5"`, `"gpt-5-mini"`. |
110
+ | `backupModels` | `string[]` | no | `[]` | Tried in order on overload/rate-limit errors. |
111
+ | `config` | OpenAI params | no | — | Defaults for `temperature`, `top_p`, etc. |
112
+ | `retryConfig.timeout` | `number` | no | `60000` | Per-attempt timeout in ms. |
113
+ | `retryConfig.retries` | `number` | no | `3` | Total attempts. |
114
+
115
+ ### Example
116
+
117
+ ```typescript
118
+ const openai = new OpenAIProvider({
119
+ apiKey: process.env.OPENAI_API_KEY!,
120
+ model: "gpt-5-mini",
121
+ organization: "org_abc",
122
+ config: { temperature: 0.2 },
123
+ });
124
+ ```
125
+
126
+ ## AnthropicProvider
127
+
128
+ ### Signature
129
+
130
+ ```typescript
131
+ new AnthropicProvider(options: AnthropicProviderOptions)
132
+
133
+ interface AnthropicProviderOptions {
134
+ apiKey: string;
135
+ model: string;
136
+ backupModels?: string[];
137
+ config?: Partial<Omit<MessageCreateParamsNonStreaming, "model" | "messages">>;
138
+ retryConfig?: { timeout?: number; retries?: number };
139
+ }
140
+ ```
141
+
142
+ ### Fields
143
+
144
+ | Field | Type | Required | Default | Notes |
145
+ |-------|------|----------|---------|-------|
146
+ | `apiKey` | `string` | yes | — | Throws if empty. |
147
+ | `model` | `string` | yes | — | e.g. `"claude-sonnet-4-5"`, `"claude-opus-4-1"`. |
148
+ | `backupModels` | `string[]` | no | `[]` | Tried in order on 429/500/503/529/overload. |
149
+ | `config` | Anthropic params | no | — | Defaults for `max_tokens`, `system`, etc. The provider sets `max_tokens=4096` if neither `config.max_tokens` nor `parameters.maxOutputTokens` is set. |
150
+ | `retryConfig.timeout` | `number` | no | `60000` | Per-attempt timeout in ms. |
151
+ | `retryConfig.retries` | `number` | no | `3` | Total attempts. |
152
+
153
+ ### Example
154
+
155
+ ```typescript
156
+ const anthropic = new AnthropicProvider({
157
+ apiKey: process.env.ANTHROPIC_API_KEY!,
158
+ model: "claude-sonnet-4-5",
159
+ config: { max_tokens: 8192 },
160
+ });
161
+ ```
162
+
163
+ ## OpenRouterProvider
164
+
165
+ OpenRouter is OpenAI-compatible and brokers many vendors behind one endpoint. Use it to A/B-test models without changing client code.
166
+
167
+ ### Signature
168
+
169
+ ```typescript
170
+ new OpenRouterProvider(options: OpenRouterProviderOptions)
171
+
172
+ interface OpenRouterProviderOptions {
173
+ apiKey: string;
174
+ model: string;
175
+ backupModels?: string[];
176
+ siteUrl?: string;
177
+ siteName?: string;
178
+ config?: Partial<Omit<ChatCompletionCreateParamsNonStreaming, "model" | "messages">>;
179
+ retryConfig?: { timeout?: number; retries?: number };
180
+ }
181
+ ```
182
+
183
+ ### Fields
184
+
185
+ | Field | Type | Required | Default | Notes |
186
+ |-------|------|----------|---------|-------|
187
+ | `apiKey` | `string` | yes | — | Throws if empty. |
188
+ | `model` | `string` | yes | — | OpenRouter model id, e.g. `"anthropic/claude-sonnet-4.5"`. See [openrouter.ai/models](https://openrouter.ai/models). |
189
+ | `backupModels` | `string[]` | no | `[]` | Tried in order on overload/capacity errors. |
190
+ | `siteUrl` | `string` | no | `""` | Sent as `HTTP-Referer` for OpenRouter rankings. |
191
+ | `siteName` | `string` | no | `""` | Sent as `X-Title` for OpenRouter rankings. |
192
+ | `config` | OpenAI params | no | — | OpenAI-shaped defaults (forwarded to OpenRouter). |
193
+ | `retryConfig.timeout` | `number` | no | `60000` | Per-attempt timeout in ms. |
194
+ | `retryConfig.retries` | `number` | no | `3` | Total attempts. |
195
+
196
+ ### Example
197
+
198
+ ```typescript
199
+ const openrouter = new OpenRouterProvider({
200
+ apiKey: process.env.OPENROUTER_API_KEY!,
201
+ model: "anthropic/claude-sonnet-4.5",
202
+ backupModels: ["openai/gpt-5-mini", "google/gemini-2.5-pro"],
203
+ siteName: "My App",
204
+ });
205
+ ```
206
+
207
+ ## Errors
208
+
209
+ All four providers share the same construction-time guards and runtime failure modes.
210
+
211
+ | When | Error | Why |
212
+ |------|-------|-----|
213
+ | `apiKey` is empty or missing | `Error("<vendor> API key is required")` | Thrown from the constructor. |
214
+ | `model` is empty or missing | `Error("Model is required. ...")` | Thrown from the constructor. |
215
+ | Vendor returns no text and no tool calls | `Error("No response from <vendor>")` | Surfaces as a `ResponseGenerationError` once it bubbles through the agent. |
216
+ | Primary and every backup model fail | The last backup error is rethrown | After exhausting `backupModels`. The agent wraps it in `ResponseGenerationError`. |
217
+ | Anthropic streaming with `system: undefined` | Vendor 400 | Set `config.system` or rely on history-derived system messages. |
218
+
219
+ The retry/backup logic only kicks in for transient errors: HTTP 429 / 500 / 503 (and 529 for Anthropic), `overloaded`-style codes, or messages containing `overloaded`, `unavailable`, `internal error`, or (OpenRouter only) `capacity`. Other errors fail fast.
220
+
221
+ ## Related
222
+
223
+ - [Install](../start/01-install.md) — provider signup and env keys
224
+ - [Architecture](../concepts/architecture.md) — where the provider sits in the engine
225
+ - [createAgent](./create-agent.md) — the `provider` field
226
+ - [Persistence adapters](./adapters.md) — the other strategy plug
227
+ - [Errors](./errors.md) — `ResponseGenerationError` and friends
@@ -0,0 +1,356 @@
1
+ ---
2
+ title: "Signals"
3
+ description: "Typed event detectors that run before and after each LLM turn, with optional structured extraction and rate-limited firing."
4
+ type: reference
5
+ order: 9
6
+ ---
7
+
8
+ # Signals
9
+
10
+ > **Where this is introduced:** [Turn pipeline](../concepts/pipeline.md)
11
+
12
+ A `Signal` is a typed event detector that runs around an LLM turn. Each signal pairs a *condition* (`when` / `if`) with a *handler* that returns a `SignalDirective`. Signals optionally carry an `extract` schema for structured data extraction beyond boolean detection, run at two pipeline phases (PRE-SIGNAL parallel with routing, POST-SIGNAL after the LLM), are rate-limited (`once` / `always` / `cooldown`), and surface their firings on `AgentResponse.triggeredSignals`.
13
+
14
+ Signals operate in two modes:
15
+
16
+ - **Detection mode** — no `extract`. Boolean match/no-match via a batched classifier call. Multiple signals share one LLM call.
17
+ - **Extraction mode** — `extract` set. Structured data extraction merged into the same batched call. The handler receives `ctx.extracted` typed by the `TExtract` generic.
18
+
19
+ When `agent.signals` is empty or undefined, both phases short-circuit to zero cost — no extra provider calls.
20
+
21
+ ## Signature
22
+
23
+ ```typescript
24
+ interface Signal<TContext = unknown, TData = unknown, TExtract = void> {
25
+ // Identity
26
+ id?: string;
27
+ title?: string;
28
+ description?: string;
29
+
30
+ // Conditions (v2 when/if split)
31
+ when?: string | string[];
32
+ if?: SignalPredicate<TContext, TData> | SignalPredicate<TContext, TData>[];
33
+
34
+ // Optional structured extraction
35
+ extract?: SignalSchema<TExtract>;
36
+
37
+ // Phase + handler
38
+ phase: 'pre' | 'post' | 'both';
39
+ handler: (ctx: SignalContext<TContext, TData, TExtract>) =>
40
+ | void
41
+ | SignalDirective<TContext, TData>
42
+ | Promise<void | SignalDirective<TContext, TData>>;
43
+
44
+ // Rate limiting
45
+ behavior?: 'once' | 'always' | 'cooldown';
46
+ cooldownMs?: number;
47
+
48
+ // Misc
49
+ enabled?: boolean;
50
+ priority?: number;
51
+ }
52
+
53
+ type SignalSchema<_T = unknown> = Record<string, unknown>;
54
+
55
+ type SignalPredicate<TContext = unknown, TData = unknown> = (
56
+ ctx: SignalPredicateContext<TContext, TData>,
57
+ ) => boolean | Promise<boolean>;
58
+
59
+ interface SignalPredicateContext<TContext = unknown, TData = unknown> {
60
+ data: Partial<TData>;
61
+ context: TContext;
62
+ session: SessionState<TData>;
63
+ history: Event[];
64
+ }
65
+
66
+ interface SignalContext<TContext = unknown, TData = unknown, TExtract = void> {
67
+ signal: Signal<TContext, TData, TExtract>;
68
+ phase: 'pre' | 'post';
69
+ matched: true;
70
+ reason: string;
71
+ extracted: TExtract extends void ? undefined : TExtract;
72
+
73
+ session: SessionState<TData>;
74
+ context: TContext;
75
+ data: Partial<TData>;
76
+ history: Event[];
77
+ lastUserMessage?: string;
78
+ triggeredAt: Date;
79
+
80
+ updateContext(updates: Partial<TContext>): Promise<void>;
81
+ updateData(updates: Partial<TData>): Promise<void>;
82
+ dispatch(directive: SignalDirective<TContext, TData>): void;
83
+ }
84
+
85
+ interface SignalDirective<TContext = unknown, TData = unknown>
86
+ extends PreDirective<TContext, TData> {
87
+ stopOtherSignals?: boolean;
88
+ replyWith?: string | ((ctx: SignalContext<TContext, TData>) => string);
89
+ }
90
+
91
+ interface SignalFiring<TContext = unknown, TData = unknown> {
92
+ id: string;
93
+ phase: 'pre' | 'post';
94
+ reason?: string;
95
+ extracted?: unknown;
96
+ directive?: SignalDirective<TContext, TData>;
97
+ handlerError?: string;
98
+ durationMs?: number;
99
+ }
100
+
101
+ interface SignalsState {
102
+ triggers: Record<string, SignalTriggerState>;
103
+ }
104
+
105
+ interface SignalTriggerState {
106
+ firstTriggeredAt: Date;
107
+ lastTriggeredAt: Date;
108
+ count: number;
109
+ lastReason?: string;
110
+ lastPhase?: 'pre' | 'post';
111
+ }
112
+ ```
113
+
114
+ Signals are wired into the agent through two `AgentOptions` fields:
115
+
116
+ ```typescript
117
+ interface AgentOptions<TContext, TData> {
118
+ // ... other fields ...
119
+ signals?: Signal<TContext, TData, unknown>[];
120
+ signalBatchSize?: number; // default 10
121
+ }
122
+ ```
123
+
124
+ ## Fields
125
+
126
+ ### `Signal`
127
+
128
+ | Field | Type | Required | Default | Notes |
129
+ |-------|------|----------|---------|-------|
130
+ | `id` | `string` | no | auto-generated | Stable identifier within a session. Used for `SignalsState.triggers` keying and on `SignalFiring`. Must be unique across the agent's signals. |
131
+ | `title` | `string` | no | — | Display title shown in logs and traces. |
132
+ | `description` | `string` | no | — | Free-text description; rendered into the classifier prompt. |
133
+ | `when` | `string \| string[]` | no | — | AI-evaluated condition(s). Entries prefixed with `!` are exclusion conditions rendered under "DO NOT TRIGGER WHEN" (OR semantics — any match inhibits firing). Non-prefixed entries render under "TRIGGER WHEN" (AND semantics — all must match). |
134
+ | `if` | `SignalPredicate \| SignalPredicate[]` | no | — | Code predicate(s). AND semantics. Free to evaluate. Runs before `when`; if any returns `false`, `when` is skipped (no token cost). |
135
+ | `extract` | `SignalSchema<TExtract>` | no | — | When set, the signal operates in extraction mode. JSON Schema object describing the per-signal `extracted` field merged into the classifier response. The `TExtract` generic carries the resulting type onto `ctx.extracted`. |
136
+ | `phase` | `'pre' \| 'post' \| 'both'` | yes | — | When the signal evaluates. `'pre'` runs in parallel with routing. `'post'` runs after the LLM call, before persistence. `'both'` evaluates in both phases. |
137
+ | `handler` | `(ctx) => void \| SignalDirective \| Promise<…>` | yes | — | Invoked when the signal fires. May return a directive, dispatch one via `ctx.dispatch`, or return void for side-effect-only behavior. |
138
+ | `behavior` | `'once' \| 'always' \| 'cooldown'` | no | `'always'` | Rate-limit / dedup mode. `'once'` fires once per session. `'cooldown'` requires `cooldownMs`. |
139
+ | `cooldownMs` | `number` | conditional | — | Required when `behavior === 'cooldown'`. Suppresses re-firing for this duration after the last trigger. Misconfiguration logs a debug warning and falls back to `'always'`. |
140
+ | `enabled` | `boolean` | no | `true` | When `false`, the signal is filtered out at the start of the phase. |
141
+ | `priority` | `number` | no | `0` | Higher priority handlers run first within a phase. Ties break by declaration order in `agent.signals`. |
142
+
143
+ ### `SignalPredicateContext`
144
+
145
+ Passed to every `if` predicate. Symmetric with `BranchPredicateContext`.
146
+
147
+ | Field | Type | Notes |
148
+ |-------|------|-------|
149
+ | `data` | `Partial<TData>` | Collected data so far. Fields not yet collected are `undefined`. |
150
+ | `context` | `TContext` | Ambient agent context. |
151
+ | `session` | `SessionState<TData>` | Full session state, including `session.signals` for inspecting prior triggers. |
152
+ | `history` | `Event[]` | Conversation history as native events. |
153
+
154
+ A predicate that throws is treated as a non-match — other signals continue evaluating.
155
+
156
+ ### `SignalContext`
157
+
158
+ Passed to handlers when a signal fires. Symmetric with `ToolContext`.
159
+
160
+ | Field | Type | Notes |
161
+ |-------|------|-------|
162
+ | `signal` | `Signal<TContext, TData, TExtract>` | The signal definition that fired. |
163
+ | `phase` | `'pre' \| 'post'` | Which phase this firing belongs to. Useful when `signal.phase === 'both'`. |
164
+ | `matched` | `true` | Always `true` when the handler runs. Typed for narrowing. |
165
+ | `reason` | `string` | AI rationale when `when` matched, or `'code-only'` / `'unconditional'`. |
166
+ | `extracted` | `TExtract extends void ? undefined : TExtract` | Extracted data when `signal.extract` is set; `undefined` for detection-only signals. |
167
+ | `session` | `SessionState<TData>` | Session state. Use writers below for mutations. |
168
+ | `context` | `TContext` | Ambient agent context. |
169
+ | `data` | `Partial<TData>` | Collected data (partial). |
170
+ | `history` | `Event[]` | Conversation history. |
171
+ | `lastUserMessage` | `string \| undefined` | Convenience accessor for the most recent user message. |
172
+ | `triggeredAt` | `Date` | Wall-clock timestamp when the handler started. |
173
+ | `updateContext` | `(updates) => Promise<void>` | Shallow-merge into `context`. Same contract as `ToolContext.updateContext`. |
174
+ | `updateData` | `(updates) => Promise<void>` | Shallow-merge into `data`. Same contract as `ToolContext.updateData`. |
175
+ | `dispatch` | `(directive) => void` | Emit a `SignalDirective` onto the per-turn bus. May be called multiple times; emissions merge by Algorithm 4 alongside hook and tool directives. |
176
+
177
+ ### `SignalDirective`
178
+
179
+ Extends [`PreDirective`](./pre-directive.md), which extends [`Directive`](./directive.md). All position fields (`goTo`, `goToStep`, `complete`, `abort`, `reset`), state writes (`dataUpdate`, `contextUpdate`), `reply`, and PreDirective extras (`appendPrompt`, `injectTools`, `halt`) are inherited unchanged.
180
+
181
+ | Added field | Type | Notes |
182
+ |-------------|------|-------|
183
+ | `stopOtherSignals` | `boolean` | When `true`, skip remaining signals in the current phase after this handler. Does not affect the other phase. Consumed inside the signal pipeline — does not enter the directive bus. |
184
+ | `replyWith` | `string \| ((ctx) => string)` | Late-binding `reply`. String form is identical to `Directive.reply`. Function form is evaluated at emit time and projected onto `reply` before bus merging. |
185
+
186
+ **Post-phase drop rules.** When a signal runs in the post-phase, `appendPrompt`, `injectTools`, and `halt` are dropped with a debug warning — they have no meaning after the LLM call has already completed. Position directives in the post-phase set `session.pendingDirective` for the *next* turn (no mid-turn re-entry).
187
+
188
+ ### `SignalFiring`
189
+
190
+ One entry per signal that fired this turn. Populated in fire order across both phases on `AgentResponse.triggeredSignals` (and on the final chunk of `AgentResponseStreamChunk`). Mirrors the observability framing of `executedSteps` and `appliedInstructions`.
191
+
192
+ | Field | Type | Notes |
193
+ |-------|------|-------|
194
+ | `id` | `string` | The signal's identifier. |
195
+ | `phase` | `'pre' \| 'post'` | Phase the signal fired in. |
196
+ | `reason` | `string \| undefined` | AI rationale, `'code-only'`, or `'unconditional'`. |
197
+ | `extracted` | `unknown` | Extracted payload when in extraction mode. |
198
+ | `directive` | `SignalDirective \| undefined` | The directive returned (or dispatched) by the handler. |
199
+ | `handlerError` | `string \| undefined` | Error message if the handler threw. The turn continues — handler errors never break a turn. |
200
+ | `durationMs` | `number \| undefined` | Wall-clock duration of the handler invocation. |
201
+
202
+ ### `SignalsState` and `SignalTriggerState`
203
+
204
+ Persisted on `session.signals`. Adapters preserve this shape bit-identical.
205
+
206
+ `SignalsState` has a single field, `triggers: Record<string, SignalTriggerState>`, keyed by `signal.id`.
207
+
208
+ | `SignalTriggerState` field | Type | Notes |
209
+ |----------------------------|------|-------|
210
+ | `firstTriggeredAt` | `Date` | When this signal first fired in the session. Never updated on subsequent fires. |
211
+ | `lastTriggeredAt` | `Date` | When this signal last fired. Drives `cooldown` arithmetic. |
212
+ | `count` | `number` | Total fires for this signal in this session. Monotonically increasing. |
213
+ | `lastReason` | `string \| undefined` | The `reason` from the most recent firing. |
214
+ | `lastPhase` | `'pre' \| 'post' \| undefined` | The phase of the most recent firing. |
215
+
216
+ ### `signalBatchSize`
217
+
218
+ Maximum signals per batched classifier call. Default `10`. When more LLM-conditioned signals are eligible after gating, they split into parallel batches of this size — each batch is one provider call, all batches run via `Promise.all`. Setting this to `0` or a non-integer throws `FlowConfigurationError` at agent construction.
219
+
220
+ ## Phase semantics
221
+
222
+ | Capability | Pre-phase | Post-phase |
223
+ |---|---|---|
224
+ | `halt` | Skips the LLM call | Dropped with debug warning |
225
+ | `reply` / `replyWith` | Replaces the message that would have been generated | Replaces the message that was just generated |
226
+ | `goTo` / `goToStep` | Overrides routing for this turn | Sets `pendingDirective` for next turn |
227
+ | `complete` | This turn closes the flow | Same |
228
+ | `appendPrompt` | Injected into this turn's response prompt | Dropped with debug warning |
229
+ | `injectTools` | Available to this turn's LLM | Dropped with debug warning |
230
+ | `dataUpdate` / `contextUpdate` | Applied before LLM, visible in prompt | Applied, persisted |
231
+ | `extract` results | Available to handler pre-LLM | Available to handler post-LLM |
232
+ | `stopOtherSignals` | Stops further pre-signals | Stops further post-signals |
233
+
234
+ ### Resolution precedence within a turn
235
+
236
+ Per turn, position decisions are resolved in this fixed order:
237
+
238
+ 1. **`session.pendingDirective`** (set last turn or via `agent.dispatch()`) — consumed first.
239
+ 2. **PRE-SIGNAL phase directives** (parallel with routing). Position fields override routing; `halt` discards routing entirely.
240
+ 3. **AI routing** — used only if (1) and (2) produced no position field.
241
+ 4. **Auto-step chain.**
242
+ 5. **Step branches.**
243
+ 6. **Linear successor / AI step selection** — final fallback.
244
+ 7. **POST-SIGNAL phase directives** — set `pendingDirective` for the *next* turn.
245
+
246
+ ## Examples
247
+
248
+ ### 1. Pre-phase halt with verbatim reply (escalation)
249
+
250
+ A handoff signal that intercepts the turn before the LLM runs, notifies a side channel, and replies with a fixed message. Cooldown prevents re-notification within the hour.
251
+
252
+ ```typescript
253
+ import type { Signal } from "@falai/agent";
254
+
255
+ type Ctx = { conversationId: string };
256
+ type Data = { topic?: string };
257
+
258
+ export const humanHandoff: Signal<Ctx, Data> = {
259
+ id: "human_handoff",
260
+ title: "Human handoff requested",
261
+ description: "Lead asks to talk to a real person.",
262
+ when: [
263
+ "the user explicitly asks to talk to a human, agent, or representative",
264
+ "the user explicitly says they do not want to talk to a bot",
265
+ "!casual mentions of people (e.g., 'my colleague said')",
266
+ "!general frustration without an explicit handoff request",
267
+ ],
268
+ phase: "pre",
269
+ behavior: "cooldown",
270
+ cooldownMs: 60 * 60_000, // 1 hour
271
+ priority: 100,
272
+ async handler({ session, lastUserMessage }) {
273
+ await notifyTeam(session.id, lastUserMessage);
274
+ return {
275
+ halt: true,
276
+ replyWith: "I'm connecting you with someone from our team. They'll reach out shortly.",
277
+ stopOtherSignals: true,
278
+ };
279
+ },
280
+ };
281
+ ```
282
+
283
+ ### 2. Post-phase extraction (entity capture)
284
+
285
+ A signal that runs after every LLM turn, extracts a structured payload, and writes it back into collected data. No `when` — it's gated by `if` on session state, then unconditionally extracts when eligible.
286
+
287
+ ```typescript
288
+ import type { Signal } from "@falai/agent";
289
+
290
+ type Data = { leadStage?: "cold" | "warm" | "hot" | "closing" };
291
+
292
+ export const leadStage: Signal<unknown, Data, { stage: Data["leadStage"]; confidence: number }> = {
293
+ id: "lead_stage",
294
+ title: "Lead stage classification",
295
+ if: ({ session }) => (session.history?.length ?? 0) > 5,
296
+ extract: {
297
+ type: "object",
298
+ properties: {
299
+ stage: { type: "string", enum: ["cold", "warm", "hot", "closing"] },
300
+ confidence: { type: "number", minimum: 0, maximum: 1 },
301
+ },
302
+ required: ["stage", "confidence"],
303
+ },
304
+ phase: "post",
305
+ behavior: "always",
306
+ async handler({ extracted, updateData }) {
307
+ if (extracted.confidence >= 0.6) {
308
+ await updateData({ leadStage: extracted.stage });
309
+ }
310
+ },
311
+ };
312
+ ```
313
+
314
+ ### 3. Cooldown behavior
315
+
316
+ A pre-phase signal that nudges the next prompt with a tone hint, suppressed for two minutes after each fire so a frustrated user isn't re-flagged on every turn.
317
+
318
+ ```typescript
319
+ import type { Signal } from "@falai/agent";
320
+
321
+ export const frustrationDetected: Signal = {
322
+ id: "frustration_detected",
323
+ when: "the user is visibly frustrated, impatient, or upset",
324
+ phase: "pre",
325
+ behavior: "cooldown",
326
+ cooldownMs: 2 * 60_000, // 2 minutes
327
+ async handler({ dispatch }) {
328
+ dispatch({
329
+ appendPrompt: ["The user is frustrated. Lead with empathy and acknowledge the issue."],
330
+ });
331
+ },
332
+ };
333
+ ```
334
+
335
+ ## Errors
336
+
337
+ Misuse surfaces as typed errors:
338
+
339
+ - `FlowConfigurationError` — duplicate `id` across `agent.signals`, invalid `extract` schema (not a JSON Schema object), `signalBatchSize` not a positive integer, or a position directive (`goTo` / `goToStep`) that resolves to an unknown flow or step.
340
+ - `DataValidationError` — `dataUpdate` (or `extracted` written via `updateData`) violates the agent schema.
341
+
342
+ Soft failures handled in-band (no thrown error, turn continues):
343
+
344
+ - **Handler throws** — recorded as `firings[i].handlerError`; iteration continues with the next signal.
345
+ - **Classifier call fails** — all LLM-conditioned signals in that batch are treated as non-match; code-only and unconditional signals continue normally.
346
+ - **Post-phase emits pre-LLM-only fields** (`halt` / `appendPrompt` / `injectTools`) — dropped with debug warning.
347
+ - **`behavior: 'cooldown'` with no `cooldownMs`** — debug warning at construction; runtime treats as `'always'`.
348
+
349
+ ## Related
350
+
351
+ - [Turn pipeline](../concepts/pipeline.md) — where signal phases sit in the turn lifecycle.
352
+ - [Directives](../concepts/directives.md) — the inheritance chain Directive → PreDirective → SignalDirective.
353
+ - [Directive](./directive.md) — base shape for all position and state fields.
354
+ - [PreDirective](./pre-directive.md) — pre-LLM extras inherited by `SignalDirective`.
355
+ - [createAgent](./create-agent.md) — `signals` and `signalBatchSize` options.
356
+ - [Errors](./errors.md) — `FlowConfigurationError` format contract.