@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
@@ -1,796 +0,0 @@
1
- # Context & Session Management
2
-
3
- ## Overview
4
-
5
- The `@falai/agent` framework provides **automatic session management** through the integrated `SessionManager` class, tracking conversation progress, collected data, and user intent across multiple turns. This enables sophisticated data-driven conversations with zero boilerplate code.
6
-
7
- ---
8
-
9
- ## 🎯 Automatic Session Management
10
-
11
- The `SessionManager` automatically tracks four key aspects of a conversation:
12
-
13
- 1. **Current Route** - Which conversation flow the user is in
14
- 2. **Current Step** - Where in the flow they currently are
15
- 3. **Agent-Level Data** - Centralized structured data collected across all routes
16
- 4. **Conversation History** - Complete message history within the session
17
-
18
- ```typescript
19
- // Define your agent-level data extraction type
20
- interface TravelData {
21
- destination: string;
22
- departureDate: string;
23
- passengers: number;
24
- cabinClass: "economy" | "business" | "first";
25
- hotelPreference?: string;
26
- budgetRange?: string;
27
- specialRequests?: string;
28
- }
29
-
30
- // Agent with automatic session management and agent-level schema
31
- const agent = new Agent<{}, TravelData>({
32
- name: "Travel Agent",
33
- provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
34
- persistence: { adapter: new PrismaAdapter({ prisma }) },
35
- sessionId: "user-123", // Automatically loads or creates session
36
-
37
- // Agent-level schema for all data collection
38
- schema: {
39
- type: "object",
40
- properties: {
41
- destination: { type: "string" },
42
- departureDate: { type: "string", format: "date" },
43
- passengers: { type: "number", minimum: 1, maximum: 9 },
44
- cabinClass: { type: "string", enum: ["economy", "business", "first"] },
45
- hotelPreference: { type: "string" },
46
- budgetRange: { type: "string" },
47
- specialRequests: { type: "string" }
48
- }
49
- }
50
- });
51
-
52
- // Simple conversation - session managed automatically
53
- const response = await agent.respond("I want to book a flight to Paris");
54
-
55
- // Access session information
56
- console.log(agent.session.id); // "user-123"
57
- console.log(agent.session.getData<TravelData>()); // { destination: "Paris", ... }
58
- console.log(agent.session.getHistory()); // Conversation history
59
- ```
60
-
61
- **Benefits of Automatic Session Management:**
62
-
63
- - **Zero Boilerplate** - No manual session creation or persistence code
64
- - **Always-On Routing** - Users can change their mind mid-conversation
65
- - **Data Persistence** - Collected data automatically saved and restored
66
- - **Context Awareness** - Router sees current progress and collected data
67
- - **History Management** - Conversation history automatically maintained
68
- - **Server-Friendly** - Perfect for stateless server environments
69
-
70
- ---
71
-
72
- ## 🔄 SessionManager API
73
-
74
- ### Session Operations
75
-
76
- ```typescript
77
- // Access the session manager
78
- const sessionManager = agent.session;
79
-
80
- // Get or create session (works for existing, new, or auto-generated IDs)
81
- await sessionManager.getOrCreate("user-123");
82
- await sessionManager.getOrCreate(); // Auto-generates ID
83
-
84
- // Agent-level data management
85
- const data = sessionManager.getData<TravelData>();
86
- await sessionManager.setData({
87
- destination: "Paris",
88
- departureDate: "2025-10-15",
89
- passengers: 2,
90
- cabinClass: "economy"
91
- });
92
-
93
- // History management
94
- await sessionManager.addMessage("user", "I want to book a flight");
95
- await sessionManager.addMessage("assistant", "Where would you like to go?");
96
- const history = sessionManager.getHistory();
97
- sessionManager.clearHistory();
98
-
99
- // Session operations
100
- await sessionManager.save(); // Manual save (auto-saves on addMessage)
101
- await sessionManager.delete();
102
- const newSession = await sessionManager.reset(true); // Preserve history
103
- ```
104
-
105
- ### Session Step Structure
106
-
107
- ```typescript
108
- interface SessionState<TData = unknown> {
109
- currentRoute?: {
110
- id: string;
111
- title: string;
112
- enteredAt: Date;
113
- };
114
- currentStep?: {
115
- id: string;
116
- description?: string;
117
- enteredAt: Date;
118
- };
119
- data: Partial<TData>; // Data collected so far
120
- routeHistory: Array<{
121
- routeId: string;
122
- routeTitle: string;
123
- enteredAt: Date;
124
- exitedAt?: Date;
125
- }>;
126
- metadata?: Record<string, unknown>;
127
- }
128
- ```
129
-
130
- ## 🔄 Enhanced Lifecycle Hooks
131
-
132
- ### Context Hooks (Traditional Context Management)
133
-
134
- ```typescript
135
- const agent = new Agent({
136
- // ... other options
137
- hooks: {
138
- // Refresh context before each response
139
- beforeRespond: async (currentContext) => {
140
- const freshData = await loadUserData(currentContext.userId);
141
- return { ...currentContext, ...freshData };
142
- },
143
-
144
- // Persist context updates
145
- onContextUpdate: async (newContext, previousContext) => {
146
- await saveUserData(newContext.userId, newContext);
147
- },
148
-
149
- // Agent-level data validation and enrichment
150
- onDataUpdate: async (data, previousData) => {
151
- // Normalize passenger count
152
- if (data.passengers < 1) data.passengers = 1;
153
- if (data.passengers > 9) data.passengers = 9;
154
-
155
- // Enrich with computed fields using agent-level data
156
- if (data.destination && !data.destinationCode) {
157
- data.destinationCode = await lookupAirportCode(data.destination);
158
- }
159
-
160
- // Auto-set budget range based on cabin class
161
- if (data.cabinClass && !data.budgetRange) {
162
- data.budgetRange = data.cabinClass === 'first' ? 'premium' :
163
- data.cabinClass === 'business' ? 'high' : 'standard';
164
- }
165
-
166
- // Auto-trigger actions when we have complete booking data
167
- if (data.destination && data.departureDate && data.passengers) {
168
- data.shouldSearchFlights = true;
169
- }
170
-
171
- return data;
172
- },
173
- },
174
- });
175
- ```
176
-
177
- ### Context Provider Pattern
178
-
179
- For always-fresh context from external sources:
180
-
181
- ```typescript
182
- const agent = new Agent({
183
- // ... other options
184
- contextProvider: async () => {
185
- // Load fresh context for each response
186
- return await loadFullContextFromDatabase();
187
- },
188
- });
189
- ```
190
-
191
- ## 📊 Data Extraction Pipeline
192
-
193
- Schema-first data extraction with intelligent step progression:
194
-
195
- ### 1. Define Your Data Schema
196
-
197
- ```typescript
198
- interface FlightData {
199
- destination: string;
200
- destinationCode?: string; // Enriched by tools
201
- departureDate: string;
202
- departureDateParsed?: string; // Enriched by tools
203
- passengers: number;
204
- cabinClass: "economy" | "business" | "first";
205
- shouldSearchFlights?: boolean; // Action flag
206
- }
207
-
208
- const route = agent.createRoute<FlightData>({
209
- title: "Book Flight",
210
- schema: {
211
- type: "object",
212
- properties: {
213
- destination: { type: "string" },
214
- departureDate: { type: "string" },
215
- passengers: { type: "number", minimum: 1, maximum: 9 },
216
- cabinClass: {
217
- type: "string",
218
- enum: ["economy", "business", "first"],
219
- default: "economy",
220
- },
221
- },
222
- required: ["destination", "departureDate", "passengers"],
223
- },
224
- initialData: {
225
- cabinClass: "economy", // Pre-populate defaults
226
- },
227
- });
228
- ```
229
-
230
- ### 2. Create Smart Step Machines
231
-
232
- ```typescript
233
- // Step with code-based logic (no fuzzy LLM conditions!)
234
- const askDestination = route.initialStep.nextStep({
235
- prompt: "Ask where they want to fly",
236
- collect: ["destination"],
237
- skipIf: (data) => !!data.destination, // Skip if already have destination
238
- });
239
-
240
- const enrichDestination = askDestination.nextStep({
241
- tool: lookupAirportCode, // Tool executes automatically
242
- requires: ["destination"], // Prerequisites
243
- });
244
-
245
- const askDates = enrichDestination.nextStep({
246
- prompt: "Ask about travel dates",
247
- collect: ["departureDate"],
248
- skipIf: (data) => !!data.departureDate,
249
- requires: ["destination"], // Must have destination first
250
- });
251
-
252
- const validateDate = askDates.nextStep({
253
- tool: parseAndValidateDate,
254
- requires: ["departureDate"],
255
- });
256
-
257
- const askPassengers = validateDate.nextStep({
258
- prompt: "How many passengers?",
259
- collect: ["passengers"],
260
- skipIf: (data) => !!data.passengers,
261
- });
262
-
263
- const searchFlights = askPassengers.nextStep({
264
- tool: searchFlightAPI,
265
- // Triggered when shouldSearchFlights flag is set by hook
266
- });
267
- ```
268
-
269
- ### 3. Tools Access Collected data
270
-
271
- ```typescript
272
- const searchFlights: Tool<Context, [], void, FlightData> = {
273
- id: "search_flights",
274
- description: "Search for available flights based on collected data",
275
- parameters: {
276
- type: "object",
277
- properties: {},
278
- },
279
- handler: async (toolContext) => {
280
- // Access collected data directly (no LLM extraction needed!)
281
- if (!toolContext.data.destination || !toolContext.data.departureDate) {
282
- return { data: undefined };
283
- }
284
-
285
- const flights = await searchFlightAPI(
286
- toolContext.data.destination,
287
- toolContext.data.departureDate
288
- );
289
-
290
- return {
291
- data: undefined,
292
- contextUpdate: { availableFlights: flights },
293
- dataUpdate: {
294
- shouldSearchFlights: false, // Clear the flag
295
- },
296
- };
297
- },
298
- };
299
- ```
300
-
301
- ### 4. Lifecycle Hooks for Validation & Enrichment
302
-
303
- ```typescript
304
- const agent = new Agent({
305
- // ... other options
306
- hooks: {
307
- onDataUpdate: async (data, previous) => {
308
- // Normalize data
309
- if (data.passengers < 1) data.passengers = 1;
310
- if (data.passengers > 9) data.passengers = 9;
311
-
312
- // Enrich data
313
- if (data.destination && !data.destinationCode) {
314
- data.destinationCode = await lookupAirportCode(data.destination);
315
- }
316
-
317
- // Auto-trigger actions
318
- if (hasAllRequires(data) && !data.shouldSearchFlights) {
319
- data.shouldSearchFlights = true;
320
- }
321
-
322
- return data;
323
- },
324
- },
325
- });
326
- ```
327
-
328
- ## 🎯 Always-On Routing with Context
329
-
330
- Routing happens every turn with full session context:
331
-
332
- ```typescript
333
- // User starts booking a flight
334
- const response1 = await agent.respond({
335
- history: [
336
- {
337
- role: "user",
338
- content: "I want to fly to Paris tomorrow with 2 people",
339
- },
340
- ],
341
- session,
342
- });
343
-
344
- // User changes mind mid-conversation
345
- const response2 = await agent.respond({
346
- history: [
347
- ...previousHistory,
348
- {
349
- role: "user",
350
- content: "Actually, make that Tokyo instead",
351
- },
352
- ],
353
- session: response1.session, // Router sees context and switches appropriately
354
- });
355
-
356
- // Router understands:
357
- // - Current route: "Book Flight"
358
- // - Current step: "ask_passengers"
359
- // - Collected data: { destination: "Paris", departureDate: "tomorrow", passengers: 2 }
360
- // - User intent: "Tokyo instead" → switches to new destination
361
- ```
362
-
363
- ## 📋 Multi-Turn Conversation Patterns
364
-
365
- ```typescript
366
- import { Agent, type ContextLifecycleHooks } from "@falai/agent";
367
-
368
- // Define hooks
369
- const hooks: ContextLifecycleHooks<MyContext> = {
370
- // Load fresh context before each response
371
- beforeRespond: async (currentContext) => {
372
- return await database.loadContext(sessionId);
373
- },
374
-
375
- // Persist context after updates
376
- onContextUpdate: async (newContext, previousContext) => {
377
- await database.saveContext(sessionId, newContext);
378
- },
379
- };
380
-
381
- // Create agent with hooks
382
- const agent = new Agent({
383
- name: "Bot",
384
- provider: provider,
385
- context: initialContext,
386
- hooks, // 🔑 Enable persistence
387
- });
388
- ```
389
-
390
- **How it works:**
391
-
392
- 1. `beforeRespond` fetches fresh context from your database before `respond()` is called
393
- 2. Tools can update context using `toolContext.updateContext()` or returning `{ contextUpdate }`
394
- 3. `onContextUpdate` automatically persists changes to your database
395
- 4. Next request creates a new agent, `beforeRespond` loads the updated context
396
-
397
- ---
398
-
399
- ## 🔧 Tool Context Updates
400
-
401
- Tools can update context in **two ways**:
402
-
403
- ### Option A: Return `contextUpdate`
404
-
405
- ```typescript
406
- const saveName: Tool<MyContext, [name: string], boolean> = {
407
- id: "save_name",
408
- description: "Save the user's name to context",
409
- parameters: {
410
- type: "object",
411
- properties: {
412
- name: { type: "string", description: "The user's name" },
413
- },
414
- required: ["name"],
415
- },
416
- handler: async (toolContext, args) => {
417
- return {
418
- data: true,
419
- contextUpdate: {
420
- userName: args.name,
421
- updatedAt: new Date(),
422
- },
423
- };
424
- },
425
- };
426
- ```
427
-
428
- **Pros:**
429
-
430
- - Declarative and functional
431
- - Easy to test
432
- - Context update is part of the result
433
-
434
- ### Option B: Call `updateContext()` directly
435
-
436
- ```typescript
437
- const saveName: Tool<MyContext, [name: string], boolean> = {
438
- id: "save_name",
439
- description: "Save the user's name to context using direct update",
440
- parameters: {
441
- type: "object",
442
- properties: {
443
- name: { type: "string", description: "The user's name" },
444
- },
445
- required: ["name"],
446
- },
447
- handler: async (toolContext, args) => {
448
- await toolContext.updateContext({
449
- userName: args.name,
450
- updatedAt: new Date(),
451
- });
452
-
453
- return { data: true };
454
- },
455
- };
456
- ```
457
-
458
- **Pros:**
459
-
460
- - More imperative and direct
461
- - Can update context at any point in the tool
462
- - Useful for complex logic
463
-
464
- **Both approaches trigger the `onContextUpdate` hook automatically.**
465
-
466
- ---
467
-
468
- ## 🌐 Context Provider Pattern
469
-
470
- For scenarios where context is **always loaded from an external source**, use the `contextProvider` pattern:
471
-
472
- ```typescript
473
- const agent = new Agent({
474
- name: "Bot",
475
- provider: provider,
476
-
477
- // Instead of static context:
478
- contextProvider: async () => {
479
- // Fetch context fresh on every respond() call
480
- return await database.loadContext(sessionId);
481
- },
482
-
483
- hooks: {
484
- // Still persist updates
485
- onContextUpdate: async (newContext) => {
486
- await database.saveContext(sessionId, newContext);
487
- },
488
- },
489
- });
490
- ```
491
-
492
- **When to use:**
493
-
494
- - Context is always loaded from a database/cache
495
- - You never have a static starting context
496
- - You want guaranteed fresh data on every request
497
-
498
- **Difference from `beforeRespond`:**
499
-
500
- - `contextProvider`: **Replaces** the context entirely
501
- - `beforeRespond`: **Updates** the existing context (can access previous step)
502
-
503
- ---
504
-
505
- ## 🎯 Complete Example: Multi-Turn Onboarding
506
-
507
- ```typescript
508
- import { Agent, type Tool } from "@falai/agent";
509
-
510
- interface OnboardingContext {
511
- sessionId: string;
512
- userId: string;
513
- businessName?: string;
514
- industry?: string;
515
- completedSteps: string[];
516
- }
517
-
518
- // Database simulation
519
- const db = {
520
- async loadSession(sessionId: string) {
521
- return await database.findSession(sessionId);
522
- },
523
- async saveSession(sessionId: string, data: Partial<OnboardingContext>) {
524
- await database.updateSession(sessionId, data);
525
- },
526
- };
527
-
528
- // Factory function for creating agents
529
- async function createOnboardingAgent(sessionId: string) {
530
- const session = await db.loadSession(sessionId);
531
-
532
- const agent = new Agent<OnboardingContext>({
533
- name: "OnboardingBot",
534
- provider: provider,
535
- context: {
536
- sessionId,
537
- userId: session.userId,
538
- businessName: session.businessName,
539
- industry: session.industry,
540
- completedSteps: session.completedSteps || [],
541
- },
542
- hooks: {
543
- // Load fresh context before responding
544
- beforeRespond: async (current) => {
545
- const fresh = await db.loadSession(sessionId);
546
- return { ...current, ...fresh };
547
- },
548
-
549
- // Persist context after updates
550
- onContextUpdate: async (newContext) => {
551
- await db.saveSession(sessionId, {
552
- businessName: newContext.businessName,
553
- industry: newContext.industry,
554
- completedSteps: newContext.completedSteps,
555
- });
556
- },
557
- },
558
- });
559
-
560
- // Define tools with context updates
561
- const saveBusinessName: Tool<OnboardingContext, [name: string], boolean> = {
562
- id: "save_business_name",
563
- description: "Save the business name and mark step as completed",
564
- parameters: {
565
- type: "object",
566
- properties: {
567
- name: { type: "string", description: "The business name" },
568
- },
569
- required: ["name"],
570
- },
571
- handler: async (toolContext, args) => {
572
- return {
573
- data: true,
574
- contextUpdate: {
575
- businessName: args.name,
576
- completedSteps: [
577
- ...toolContext.context.completedSteps,
578
- "business_name",
579
- ],
580
- },
581
- };
582
- },
583
- };
584
-
585
- const saveIndustry: Tool<OnboardingContext, [industry: string], boolean> = {
586
- id: "save_industry",
587
- description: "Save the industry and mark step as completed",
588
- parameters: {
589
- type: "object",
590
- properties: {
591
- industry: { type: "string", description: "The business industry" },
592
- },
593
- required: ["industry"],
594
- },
595
- handler: async (toolContext, args) => {
596
- // Alternative: use updateContext directly
597
- await toolContext.updateContext({
598
- industry: args.industry,
599
- completedSteps: [...toolContext.context.completedSteps, "industry"],
600
- });
601
-
602
- return { data: true };
603
- },
604
- };
605
-
606
- // Build conversation routes...
607
- const route = agent.createRoute({ title: "Onboarding" });
608
- // ...
609
-
610
- return agent;
611
- }
612
-
613
- // Usage across multiple turns
614
- async function handleUserMessage(sessionId: string, message: string) {
615
- // Recreate agent for each turn (context is loaded fresh)
616
- const agent = await createOnboardingAgent(sessionId);
617
-
618
- const response = await agent.respond({
619
- history: [
620
- {
621
- role: "user",
622
- content: message,
623
- },
624
- ],
625
- });
626
-
627
- return response.message;
628
- }
629
- ```
630
-
631
- ---
632
-
633
- ## 📋 Best Practices
634
-
635
- ### ✅ DO
636
-
637
- - **Recreate agents** for each request in multi-turn conversations
638
- - **Use lifecycle hooks** to integrate with your database
639
- - **Store context** in your database/cache (Redis, PostgreSQL, etc.)
640
- - **Load fresh context** via `beforeRespond` or `contextProvider`
641
- - **Test persistence** by simulating multiple turns
642
- - **Handle errors** in hooks gracefully (fallback to current context)
643
-
644
- ### ❌ DON'T
645
-
646
- - **Cache agent instances** across requests (context gets stale)
647
- - **Mutate context directly** without using `updateContext()` or `contextUpdate`
648
- - **Rely on in-memory step** for multi-turn conversations
649
- - **Forget to handle** `onContextUpdate` failures (could lose data)
650
- - **Mix** `context` and `contextProvider` (will throw an error)
651
-
652
- ---
653
-
654
- ## 🔍 Debugging Context Issues
655
-
656
- ### Problem: Context updates aren't persisting
657
-
658
- **Check:**
659
-
660
- 1. Are you using `onContextUpdate` hook?
661
- 2. Is your database save actually working?
662
- 3. Are you recreating the agent with fresh context each turn?
663
-
664
- ```typescript
665
- // Debug your hooks
666
- hooks: {
667
- beforeRespond: async (current) => {
668
- console.log("📥 Loading context:", current);
669
- const fresh = await db.load(sessionId);
670
- console.log("✅ Loaded fresh:", fresh);
671
- return fresh;
672
- },
673
-
674
- onContextUpdate: async (newContext) => {
675
- console.log("💾 Saving context:", newContext);
676
- await db.save(sessionId, newContext);
677
- console.log("✅ Saved successfully");
678
- },
679
- },
680
- ```
681
-
682
- ### Problem: Context is null/undefined
683
-
684
- **Check:**
685
-
686
- 1. Did you provide either `context` or `contextProvider`?
687
- 2. Is your `contextProvider` returning valid data?
688
- 3. Is `beforeRespond` returning valid context?
689
-
690
- ```typescript
691
- // Validate your contextProvider
692
- contextProvider: async () => {
693
- const ctx = await db.load(sessionId);
694
- if (!ctx) {
695
- console.error("❌ Context not found!");
696
- throw new Error("Session not found");
697
- }
698
- return ctx;
699
- },
700
- ```
701
-
702
- ### Problem: Tools not updating context
703
-
704
- **Check:**
705
-
706
- 1. Are you returning `{ contextUpdate }` or calling `toolContext.updateContext()`?
707
- 2. Is `onContextUpdate` being called? (Add console.log)
708
- 3. Are your tools being executed at all?
709
-
710
- ---
711
-
712
- ## 🚀 Advanced Patterns
713
-
714
- ### Pattern: Context Versioning
715
-
716
- ```typescript
717
- interface VersionedContext extends MyContext {
718
- version: number;
719
- }
720
-
721
- hooks: {
722
- onContextUpdate: async (newContext) => {
723
- await db.save(sessionId, {
724
- ...newContext,
725
- version: newContext.version + 1,
726
- });
727
- },
728
-
729
- beforeRespond: async (current) => {
730
- const fresh = await db.load(sessionId);
731
- if (fresh.version > current.version) {
732
- console.log("⚠️ Context changed by another request!");
733
- }
734
- return fresh;
735
- },
736
- },
737
- ```
738
-
739
- ### Pattern: Selective Persistence
740
-
741
- ```typescript
742
- // Only persist specific fields
743
- hooks: {
744
- onContextUpdate: async (newContext) => {
745
- // Don't persist temporary/computed fields
746
- const { tempData, ...persistable } = newContext;
747
- await db.save(sessionId, persistable);
748
- },
749
- },
750
- ```
751
-
752
- ### Pattern: Multi-User Context
753
-
754
- ```typescript
755
- interface MultiUserContext {
756
- conversationId: string;
757
- participants: Map<string, UserData>;
758
- }
759
-
760
- hooks: {
761
- beforeRespond: async (current) => {
762
- // Load all participant data
763
- const conversation = await db.loadConversation(conversationId);
764
- return {
765
- conversationId,
766
- participants: new Map(conversation.participants),
767
- };
768
- },
769
- },
770
- ```
771
-
772
- ---
773
-
774
- ## 📚 Related Resources
775
-
776
- - [Complete Example: Persistent Onboarding](../../../examples/advanced-patterns/persistent-onboarding.ts)
777
- - [API Reference: AgentOptions](../../api/overview.md#agentoptions)
778
- - [API Reference: ContextLifecycleHooks](../../api/overview.md#contextlifecyclehooks)
779
- - [Getting Started](../../guides/getting-started/README.md)
780
-
781
- ---
782
-
783
- ## 🆘 Need Help?
784
-
785
- If you're still having issues:
786
-
787
- 1. Check the [examples](../../../examples/) for working implementations
788
- 2. Review the [API Reference](../../api/README.md) for detailed type information
789
- 3. Open an issue on GitHub with your use case
790
-
791
- **Remember:** The key to persistent conversations is:
792
-
793
- 1. **Recreate agents** each turn
794
- 2. **Load fresh context** via hooks/provider
795
- 3. **Persist updates** via `onContextUpdate`
796
- 4. **Never cache** agent instances across requests