@falai/agent 0.8.1 → 0.9.0-alpha-2

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 (665) hide show
  1. package/README.md +332 -147
  2. package/dist/{adapters → cjs/src/adapters}/MemoryAdapter.d.ts +4 -4
  3. package/dist/cjs/src/adapters/MemoryAdapter.d.ts.map +1 -0
  4. package/dist/cjs/{adapters → src/adapters}/MemoryAdapter.js +41 -21
  5. package/dist/cjs/src/adapters/MemoryAdapter.js.map +1 -0
  6. package/dist/{adapters → cjs/src/adapters}/MongoAdapter.d.ts +3 -3
  7. package/dist/cjs/src/adapters/MongoAdapter.d.ts.map +1 -0
  8. package/dist/cjs/{adapters → src/adapters}/MongoAdapter.js +2 -1
  9. package/dist/cjs/src/adapters/MongoAdapter.js.map +1 -0
  10. package/dist/cjs/{adapters → src/adapters}/OpenSearchAdapter.d.ts +3 -3
  11. package/dist/cjs/src/adapters/OpenSearchAdapter.d.ts.map +1 -0
  12. package/dist/cjs/{adapters → src/adapters}/OpenSearchAdapter.js +10 -13
  13. package/dist/cjs/src/adapters/OpenSearchAdapter.js.map +1 -0
  14. package/dist/cjs/{adapters → src/adapters}/PostgreSQLAdapter.d.ts +3 -3
  15. package/dist/cjs/src/adapters/PostgreSQLAdapter.d.ts.map +1 -0
  16. package/dist/cjs/{adapters → src/adapters}/PostgreSQLAdapter.js +1 -1
  17. package/dist/cjs/src/adapters/PostgreSQLAdapter.js.map +1 -0
  18. package/dist/cjs/{adapters → src/adapters}/PrismaAdapter.d.ts +3 -3
  19. package/dist/cjs/src/adapters/PrismaAdapter.d.ts.map +1 -0
  20. package/dist/cjs/{adapters → src/adapters}/PrismaAdapter.js +35 -5
  21. package/dist/cjs/src/adapters/PrismaAdapter.js.map +1 -0
  22. package/dist/cjs/{adapters → src/adapters}/RedisAdapter.d.ts +3 -3
  23. package/dist/cjs/src/adapters/RedisAdapter.d.ts.map +1 -0
  24. package/dist/cjs/{adapters → src/adapters}/RedisAdapter.js +3 -2
  25. package/dist/cjs/src/adapters/RedisAdapter.js.map +1 -0
  26. package/dist/{adapters → cjs/src/adapters}/SQLiteAdapter.d.ts +3 -3
  27. package/dist/cjs/src/adapters/SQLiteAdapter.d.ts.map +1 -0
  28. package/dist/cjs/{adapters → src/adapters}/SQLiteAdapter.js +2 -1
  29. package/dist/cjs/src/adapters/SQLiteAdapter.js.map +1 -0
  30. package/dist/cjs/src/adapters/index.d.ts.map +1 -0
  31. package/dist/cjs/src/adapters/index.js.map +1 -0
  32. package/dist/cjs/src/constants/index.d.ts.map +1 -0
  33. package/dist/cjs/src/constants/index.js.map +1 -0
  34. package/dist/cjs/src/core/Agent.d.ts +223 -0
  35. package/dist/cjs/src/core/Agent.d.ts.map +1 -0
  36. package/dist/cjs/src/core/Agent.js +1660 -0
  37. package/dist/cjs/src/core/Agent.js.map +1 -0
  38. package/dist/cjs/src/core/Events.d.ts +26 -0
  39. package/dist/cjs/src/core/Events.d.ts.map +1 -0
  40. package/dist/cjs/src/core/Events.js +144 -0
  41. package/dist/cjs/src/core/Events.js.map +1 -0
  42. package/dist/{core → cjs/src/core}/PersistenceManager.d.ts +21 -19
  43. package/dist/cjs/src/core/PersistenceManager.d.ts.map +1 -0
  44. package/dist/cjs/{core → src/core}/PersistenceManager.js +73 -20
  45. package/dist/cjs/src/core/PersistenceManager.js.map +1 -0
  46. package/dist/cjs/src/core/PromptComposer.d.ts +27 -0
  47. package/dist/cjs/src/core/PromptComposer.d.ts.map +1 -0
  48. package/dist/cjs/src/core/PromptComposer.js +157 -0
  49. package/dist/cjs/src/core/PromptComposer.js.map +1 -0
  50. package/dist/cjs/src/core/ResponseEngine.d.ts +32 -0
  51. package/dist/cjs/src/core/ResponseEngine.d.ts.map +1 -0
  52. package/dist/cjs/src/core/ResponseEngine.js +84 -0
  53. package/dist/cjs/src/core/ResponseEngine.js.map +1 -0
  54. package/dist/cjs/src/core/ResponsePipeline.d.ts +171 -0
  55. package/dist/cjs/src/core/ResponsePipeline.d.ts.map +1 -0
  56. package/dist/cjs/src/core/ResponsePipeline.js +514 -0
  57. package/dist/cjs/src/core/ResponsePipeline.js.map +1 -0
  58. package/dist/cjs/src/core/Route.d.ts +145 -0
  59. package/dist/cjs/src/core/Route.d.ts.map +1 -0
  60. package/dist/cjs/src/core/Route.js +343 -0
  61. package/dist/cjs/src/core/Route.js.map +1 -0
  62. package/dist/cjs/src/core/RoutingEngine.d.ts +129 -0
  63. package/dist/cjs/src/core/RoutingEngine.d.ts.map +1 -0
  64. package/dist/cjs/{core → src/core}/RoutingEngine.js +215 -117
  65. package/dist/cjs/src/core/RoutingEngine.js.map +1 -0
  66. package/dist/cjs/src/core/SessionManager.d.ts +86 -0
  67. package/dist/cjs/src/core/SessionManager.d.ts.map +1 -0
  68. package/dist/cjs/src/core/SessionManager.js +217 -0
  69. package/dist/cjs/src/core/SessionManager.js.map +1 -0
  70. package/dist/cjs/src/core/Step.d.ts +96 -0
  71. package/dist/cjs/src/core/Step.d.ts.map +1 -0
  72. package/dist/cjs/src/core/Step.js +206 -0
  73. package/dist/cjs/src/core/Step.js.map +1 -0
  74. package/dist/cjs/src/core/ToolExecutor.d.ts +45 -0
  75. package/dist/cjs/src/core/ToolExecutor.d.ts.map +1 -0
  76. package/dist/cjs/{core → src/core}/ToolExecutor.js +30 -19
  77. package/dist/cjs/src/core/ToolExecutor.js.map +1 -0
  78. package/dist/{index.d.ts → cjs/src/index.d.ts} +7 -15
  79. package/dist/cjs/src/index.d.ts.map +1 -0
  80. package/dist/cjs/{index.js → src/index.js} +21 -19
  81. package/dist/cjs/src/index.js.map +1 -0
  82. package/dist/cjs/{providers → src/providers}/AnthropicProvider.d.ts +1 -1
  83. package/dist/cjs/src/providers/AnthropicProvider.d.ts.map +1 -0
  84. package/dist/cjs/{providers → src/providers}/AnthropicProvider.js +54 -2
  85. package/dist/cjs/src/providers/AnthropicProvider.js.map +1 -0
  86. package/dist/{providers → cjs/src/providers}/GeminiProvider.d.ts +1 -1
  87. package/dist/cjs/src/providers/GeminiProvider.d.ts.map +1 -0
  88. package/dist/cjs/{providers → src/providers}/GeminiProvider.js +65 -0
  89. package/dist/cjs/src/providers/GeminiProvider.js.map +1 -0
  90. package/dist/cjs/{providers → src/providers}/OpenAIProvider.d.ts +1 -1
  91. package/dist/cjs/src/providers/OpenAIProvider.d.ts.map +1 -0
  92. package/dist/cjs/{providers → src/providers}/OpenAIProvider.js +70 -1
  93. package/dist/cjs/src/providers/OpenAIProvider.js.map +1 -0
  94. package/dist/{providers → cjs/src/providers}/OpenRouterProvider.d.ts +1 -1
  95. package/dist/cjs/src/providers/OpenRouterProvider.d.ts.map +1 -0
  96. package/dist/cjs/{providers → src/providers}/OpenRouterProvider.js +76 -0
  97. package/dist/cjs/src/providers/OpenRouterProvider.js.map +1 -0
  98. package/dist/cjs/src/providers/index.d.ts.map +1 -0
  99. package/dist/cjs/src/providers/index.js.map +1 -0
  100. package/dist/cjs/{types → src/types}/agent.d.ts +80 -41
  101. package/dist/cjs/src/types/agent.d.ts.map +1 -0
  102. package/dist/cjs/src/types/agent.js.map +1 -0
  103. package/dist/cjs/{types → src/types}/ai.d.ts +7 -0
  104. package/dist/cjs/src/types/ai.d.ts.map +1 -0
  105. package/dist/cjs/src/types/ai.js.map +1 -0
  106. package/dist/{types → cjs/src/types}/history.d.ts +76 -18
  107. package/dist/cjs/src/types/history.d.ts.map +1 -0
  108. package/dist/cjs/src/types/history.js +33 -0
  109. package/dist/cjs/src/types/history.js.map +1 -0
  110. package/dist/cjs/src/types/index.d.ts +20 -0
  111. package/dist/cjs/src/types/index.d.ts.map +1 -0
  112. package/dist/cjs/src/types/index.js +30 -0
  113. package/dist/cjs/src/types/index.js.map +1 -0
  114. package/dist/{types → cjs/src/types}/persistence.d.ts +38 -23
  115. package/dist/cjs/src/types/persistence.d.ts.map +1 -0
  116. package/dist/cjs/src/types/persistence.js.map +1 -0
  117. package/dist/cjs/src/types/route.d.ts +235 -0
  118. package/dist/cjs/src/types/route.d.ts.map +1 -0
  119. package/dist/cjs/{types → src/types}/route.js.map +1 -1
  120. package/dist/cjs/src/types/routing.d.ts.map +1 -0
  121. package/dist/{types → cjs/src/types}/routing.js.map +1 -1
  122. package/dist/cjs/src/types/schema.d.ts.map +1 -0
  123. package/dist/{types → cjs/src/types}/schema.js.map +1 -1
  124. package/dist/cjs/src/types/session.d.ts +65 -0
  125. package/dist/cjs/src/types/session.d.ts.map +1 -0
  126. package/dist/cjs/src/types/session.js +6 -0
  127. package/dist/cjs/src/types/session.js.map +1 -0
  128. package/dist/cjs/src/types/template.d.ts +30 -0
  129. package/dist/cjs/src/types/template.d.ts.map +1 -0
  130. package/dist/cjs/src/types/template.js +3 -0
  131. package/dist/cjs/src/types/template.js.map +1 -0
  132. package/dist/{types → cjs/src/types}/tool.d.ts +17 -13
  133. package/dist/cjs/src/types/tool.d.ts.map +1 -0
  134. package/dist/cjs/{types → src/types}/tool.js.map +1 -1
  135. package/dist/cjs/src/utils/clone.d.ts +8 -0
  136. package/dist/cjs/src/utils/clone.d.ts.map +1 -0
  137. package/dist/cjs/src/utils/clone.js +36 -0
  138. package/dist/cjs/src/utils/clone.js.map +1 -0
  139. package/dist/{utils → cjs/src/utils}/event.d.ts +1 -1
  140. package/dist/cjs/src/utils/event.d.ts.map +1 -0
  141. package/dist/cjs/{utils → src/utils}/event.js +2 -2
  142. package/dist/cjs/src/utils/event.js.map +1 -0
  143. package/dist/cjs/src/utils/history.d.ts +31 -0
  144. package/dist/cjs/src/utils/history.d.ts.map +1 -0
  145. package/dist/cjs/src/utils/history.js +128 -0
  146. package/dist/cjs/src/utils/history.js.map +1 -0
  147. package/dist/cjs/src/utils/id.d.ts.map +1 -0
  148. package/dist/cjs/src/utils/id.js.map +1 -0
  149. package/dist/cjs/src/utils/index.d.ts +13 -0
  150. package/dist/cjs/src/utils/index.d.ts.map +1 -0
  151. package/dist/cjs/src/utils/index.js +49 -0
  152. package/dist/cjs/src/utils/index.js.map +1 -0
  153. package/dist/cjs/src/utils/logger.d.ts.map +1 -0
  154. package/dist/cjs/src/utils/logger.js.map +1 -0
  155. package/dist/cjs/src/utils/retry.d.ts.map +1 -0
  156. package/dist/cjs/src/utils/retry.js.map +1 -0
  157. package/dist/cjs/src/utils/session.d.ts +51 -0
  158. package/dist/cjs/src/utils/session.d.ts.map +1 -0
  159. package/dist/cjs/{types → src/utils}/session.js +35 -32
  160. package/dist/cjs/src/utils/session.js.map +1 -0
  161. package/dist/cjs/src/utils/template.d.ts +107 -0
  162. package/dist/cjs/src/utils/template.d.ts.map +1 -0
  163. package/dist/cjs/src/utils/template.js +283 -0
  164. package/dist/cjs/src/utils/template.js.map +1 -0
  165. package/dist/{cjs → src}/adapters/MemoryAdapter.d.ts +4 -4
  166. package/dist/src/adapters/MemoryAdapter.d.ts.map +1 -0
  167. package/dist/{adapters → src/adapters}/MemoryAdapter.js +41 -21
  168. package/dist/src/adapters/MemoryAdapter.js.map +1 -0
  169. package/dist/{cjs → src}/adapters/MongoAdapter.d.ts +3 -3
  170. package/dist/src/adapters/MongoAdapter.d.ts.map +1 -0
  171. package/dist/{adapters → src/adapters}/MongoAdapter.js +2 -1
  172. package/dist/src/adapters/MongoAdapter.js.map +1 -0
  173. package/dist/{adapters → src/adapters}/OpenSearchAdapter.d.ts +3 -3
  174. package/dist/src/adapters/OpenSearchAdapter.d.ts.map +1 -0
  175. package/dist/{adapters → src/adapters}/OpenSearchAdapter.js +10 -13
  176. package/dist/src/adapters/OpenSearchAdapter.js.map +1 -0
  177. package/dist/{adapters → src/adapters}/PostgreSQLAdapter.d.ts +3 -3
  178. package/dist/src/adapters/PostgreSQLAdapter.d.ts.map +1 -0
  179. package/dist/{adapters → src/adapters}/PostgreSQLAdapter.js +1 -1
  180. package/dist/src/adapters/PostgreSQLAdapter.js.map +1 -0
  181. package/dist/{adapters → src/adapters}/PrismaAdapter.d.ts +3 -3
  182. package/dist/src/adapters/PrismaAdapter.d.ts.map +1 -0
  183. package/dist/{adapters → src/adapters}/PrismaAdapter.js +35 -5
  184. package/dist/src/adapters/PrismaAdapter.js.map +1 -0
  185. package/dist/{adapters → src/adapters}/RedisAdapter.d.ts +3 -3
  186. package/dist/src/adapters/RedisAdapter.d.ts.map +1 -0
  187. package/dist/{adapters → src/adapters}/RedisAdapter.js +3 -2
  188. package/dist/src/adapters/RedisAdapter.js.map +1 -0
  189. package/dist/{cjs → src}/adapters/SQLiteAdapter.d.ts +3 -3
  190. package/dist/src/adapters/SQLiteAdapter.d.ts.map +1 -0
  191. package/dist/{adapters → src/adapters}/SQLiteAdapter.js +2 -1
  192. package/dist/src/adapters/SQLiteAdapter.js.map +1 -0
  193. package/dist/src/adapters/index.js.map +1 -0
  194. package/dist/src/constants/index.js.map +1 -0
  195. package/dist/src/core/Agent.d.ts +223 -0
  196. package/dist/src/core/Agent.d.ts.map +1 -0
  197. package/dist/src/core/Agent.js +1656 -0
  198. package/dist/src/core/Agent.js.map +1 -0
  199. package/dist/src/core/Events.d.ts +26 -0
  200. package/dist/src/core/Events.d.ts.map +1 -0
  201. package/dist/src/core/Events.js +137 -0
  202. package/dist/src/core/Events.js.map +1 -0
  203. package/dist/{cjs → src}/core/PersistenceManager.d.ts +21 -19
  204. package/dist/src/core/PersistenceManager.d.ts.map +1 -0
  205. package/dist/{core → src/core}/PersistenceManager.js +71 -18
  206. package/dist/src/core/PersistenceManager.js.map +1 -0
  207. package/dist/src/core/PromptComposer.d.ts +27 -0
  208. package/dist/src/core/PromptComposer.d.ts.map +1 -0
  209. package/dist/src/core/PromptComposer.js +153 -0
  210. package/dist/src/core/PromptComposer.js.map +1 -0
  211. package/dist/src/core/ResponseEngine.d.ts +32 -0
  212. package/dist/src/core/ResponseEngine.d.ts.map +1 -0
  213. package/dist/src/core/ResponseEngine.js +80 -0
  214. package/dist/src/core/ResponseEngine.js.map +1 -0
  215. package/dist/src/core/ResponsePipeline.d.ts +171 -0
  216. package/dist/src/core/ResponsePipeline.d.ts.map +1 -0
  217. package/dist/src/core/ResponsePipeline.js +510 -0
  218. package/dist/src/core/ResponsePipeline.js.map +1 -0
  219. package/dist/src/core/Route.d.ts +145 -0
  220. package/dist/src/core/Route.d.ts.map +1 -0
  221. package/dist/src/core/Route.js +339 -0
  222. package/dist/src/core/Route.js.map +1 -0
  223. package/dist/src/core/RoutingEngine.d.ts +129 -0
  224. package/dist/src/core/RoutingEngine.d.ts.map +1 -0
  225. package/dist/{core → src/core}/RoutingEngine.js +211 -113
  226. package/dist/src/core/RoutingEngine.js.map +1 -0
  227. package/dist/src/core/SessionManager.d.ts +86 -0
  228. package/dist/src/core/SessionManager.d.ts.map +1 -0
  229. package/dist/src/core/SessionManager.js +213 -0
  230. package/dist/src/core/SessionManager.js.map +1 -0
  231. package/dist/src/core/Step.d.ts +96 -0
  232. package/dist/src/core/Step.d.ts.map +1 -0
  233. package/dist/src/core/Step.js +202 -0
  234. package/dist/src/core/Step.js.map +1 -0
  235. package/dist/src/core/ToolExecutor.d.ts +45 -0
  236. package/dist/src/core/ToolExecutor.d.ts.map +1 -0
  237. package/dist/src/core/ToolExecutor.js +80 -0
  238. package/dist/src/core/ToolExecutor.js.map +1 -0
  239. package/dist/{cjs → src}/index.d.ts +7 -15
  240. package/dist/src/index.d.ts.map +1 -0
  241. package/dist/{index.js → src/index.js} +6 -7
  242. package/dist/src/index.js.map +1 -0
  243. package/dist/{providers → src/providers}/AnthropicProvider.d.ts +1 -1
  244. package/dist/src/providers/AnthropicProvider.d.ts.map +1 -0
  245. package/dist/{providers → src/providers}/AnthropicProvider.js +54 -2
  246. package/dist/src/providers/AnthropicProvider.js.map +1 -0
  247. package/dist/{cjs → src}/providers/GeminiProvider.d.ts +1 -1
  248. package/dist/{cjs → src}/providers/GeminiProvider.d.ts.map +1 -1
  249. package/dist/{providers → src/providers}/GeminiProvider.js +65 -0
  250. package/dist/src/providers/GeminiProvider.js.map +1 -0
  251. package/dist/{providers → src/providers}/OpenAIProvider.d.ts +1 -1
  252. package/dist/{cjs → src}/providers/OpenAIProvider.d.ts.map +1 -1
  253. package/dist/{providers → src/providers}/OpenAIProvider.js +70 -1
  254. package/dist/src/providers/OpenAIProvider.js.map +1 -0
  255. package/dist/{cjs → src}/providers/OpenRouterProvider.d.ts +1 -1
  256. package/dist/{cjs → src}/providers/OpenRouterProvider.d.ts.map +1 -1
  257. package/dist/{providers → src/providers}/OpenRouterProvider.js +76 -0
  258. package/dist/src/providers/OpenRouterProvider.js.map +1 -0
  259. package/dist/src/providers/index.js.map +1 -0
  260. package/dist/{types → src/types}/agent.d.ts +80 -41
  261. package/dist/src/types/agent.d.ts.map +1 -0
  262. package/dist/src/types/agent.js.map +1 -0
  263. package/dist/{types → src/types}/ai.d.ts +7 -0
  264. package/dist/src/types/ai.d.ts.map +1 -0
  265. package/dist/{cjs → src}/types/ai.js.map +1 -1
  266. package/dist/{cjs → src}/types/history.d.ts +76 -18
  267. package/dist/src/types/history.d.ts.map +1 -0
  268. package/dist/src/types/history.js +30 -0
  269. package/dist/src/types/history.js.map +1 -0
  270. package/dist/src/types/index.d.ts +20 -0
  271. package/dist/src/types/index.d.ts.map +1 -0
  272. package/dist/src/types/index.js +10 -0
  273. package/dist/src/types/index.js.map +1 -0
  274. package/dist/{cjs → src}/types/persistence.d.ts +38 -23
  275. package/dist/src/types/persistence.d.ts.map +1 -0
  276. package/dist/src/types/persistence.js.map +1 -0
  277. package/dist/src/types/route.d.ts +235 -0
  278. package/dist/src/types/route.d.ts.map +1 -0
  279. package/dist/{types → src/types}/route.js.map +1 -1
  280. package/dist/src/types/session.d.ts +65 -0
  281. package/dist/src/types/session.d.ts.map +1 -0
  282. package/dist/src/types/session.js +5 -0
  283. package/dist/src/types/session.js.map +1 -0
  284. package/dist/src/types/template.d.ts +30 -0
  285. package/dist/src/types/template.d.ts.map +1 -0
  286. package/dist/src/types/template.js +2 -0
  287. package/dist/src/types/template.js.map +1 -0
  288. package/dist/{cjs → src}/types/tool.d.ts +17 -13
  289. package/dist/src/types/tool.d.ts.map +1 -0
  290. package/dist/{types → src/types}/tool.js.map +1 -1
  291. package/dist/src/utils/clone.d.ts +8 -0
  292. package/dist/src/utils/clone.d.ts.map +1 -0
  293. package/dist/src/utils/clone.js +33 -0
  294. package/dist/src/utils/clone.js.map +1 -0
  295. package/dist/{cjs → src}/utils/event.d.ts +1 -1
  296. package/dist/{cjs → src}/utils/event.d.ts.map +1 -1
  297. package/dist/{utils → src/utils}/event.js +1 -1
  298. package/dist/src/utils/event.js.map +1 -0
  299. package/dist/src/utils/history.d.ts +31 -0
  300. package/dist/src/utils/history.d.ts.map +1 -0
  301. package/dist/src/utils/history.js +121 -0
  302. package/dist/src/utils/history.js.map +1 -0
  303. package/dist/src/utils/id.js.map +1 -0
  304. package/dist/src/utils/index.d.ts +13 -0
  305. package/dist/src/utils/index.d.ts.map +1 -0
  306. package/dist/src/utils/index.js +19 -0
  307. package/dist/src/utils/index.js.map +1 -0
  308. package/dist/src/utils/logger.js.map +1 -0
  309. package/dist/src/utils/retry.js.map +1 -0
  310. package/dist/src/utils/session.d.ts +51 -0
  311. package/dist/src/utils/session.d.ts.map +1 -0
  312. package/dist/{types → src/utils}/session.js +33 -32
  313. package/dist/src/utils/session.js.map +1 -0
  314. package/dist/src/utils/template.d.ts +107 -0
  315. package/dist/src/utils/template.d.ts.map +1 -0
  316. package/dist/src/utils/template.js +276 -0
  317. package/dist/src/utils/template.js.map +1 -0
  318. package/docs/README.md +174 -68
  319. package/docs/{API_REFERENCE.md → api/README.md} +925 -255
  320. package/docs/api/overview.md +952 -0
  321. package/docs/core/agent/README.md +787 -0
  322. package/docs/{CONTEXT_MANAGEMENT.md → core/agent/context-management.md} +175 -102
  323. package/docs/{ARCHITECTURE.md → core/agent/session-management.md} +117 -69
  324. package/docs/core/ai-integration/prompt-composition.md +220 -0
  325. package/docs/core/ai-integration/providers.md +515 -0
  326. package/docs/core/ai-integration/response-processing.md +176 -0
  327. package/docs/core/conversation-flows/data-collection.md +623 -0
  328. package/docs/core/conversation-flows/route-dsl.md +502 -0
  329. package/docs/core/conversation-flows/routes.md +117 -0
  330. package/docs/core/conversation-flows/step-transitions.md +595 -0
  331. package/docs/core/conversation-flows/steps.md +154 -0
  332. package/docs/{ADAPTERS.md → core/persistence/adapters.md} +1 -1
  333. package/docs/core/persistence/session-storage.md +644 -0
  334. package/docs/core/routing/intelligent-routing.md +348 -0
  335. package/docs/core/tools/tool-definition.md +346 -0
  336. package/docs/core/tools/tool-execution.md +815 -0
  337. package/docs/core/tools/tool-scoping.md +628 -0
  338. package/docs/guides/getting-started/README.md +406 -0
  339. package/examples/{company-qna-agent.ts → advanced-patterns/knowledge-based-agent.ts} +139 -95
  340. package/examples/{persistent-onboarding.ts → advanced-patterns/persistent-onboarding.ts} +244 -137
  341. package/examples/{rules-prohibitions.ts → advanced-patterns/route-lifecycle-hooks.ts} +130 -84
  342. package/examples/{streaming-agent.ts → advanced-patterns/streaming-responses.ts} +116 -90
  343. package/examples/ai-providers/anthropic-integration.ts +384 -0
  344. package/examples/{openai-agent.ts → ai-providers/openai-integration.ts} +57 -63
  345. package/examples/conversation-flows/completion-transitions.ts +277 -0
  346. package/examples/core-concepts/basic-agent.ts +443 -0
  347. package/examples/core-concepts/schema-driven-extraction.ts +305 -0
  348. package/examples/core-concepts/session-management.ts +406 -0
  349. package/examples/integrations/database-integration.ts +630 -0
  350. package/examples/integrations/healthcare-integration.ts +609 -0
  351. package/examples/{opensearch-persistence.ts → integrations/search-integration.ts} +199 -171
  352. package/examples/integrations/server-session-management.ts +307 -0
  353. package/examples/persistence/custom-adapter.ts +529 -0
  354. package/examples/{prisma-persistence.ts → persistence/database-persistence.ts} +215 -272
  355. package/examples/persistence/memory-sessions.ts +495 -0
  356. package/examples/{prisma-schema.example.prisma → persistence/prisma-schema.example.prisma} +1 -1
  357. package/examples/persistence/redis-persistence.ts +490 -0
  358. package/examples/tools/basic-tools.ts +561 -0
  359. package/examples/{extracted-data-modification.ts → tools/data-enrichment-tools.ts} +128 -117
  360. package/package.json +14 -10
  361. package/src/adapters/MemoryAdapter.ts +74 -46
  362. package/src/adapters/MongoAdapter.ts +33 -24
  363. package/src/adapters/OpenSearchAdapter.ts +41 -37
  364. package/src/adapters/PostgreSQLAdapter.ts +35 -24
  365. package/src/adapters/PrismaAdapter.ts +69 -27
  366. package/src/adapters/RedisAdapter.ts +38 -26
  367. package/src/adapters/SQLiteAdapter.ts +32 -22
  368. package/src/core/Agent.ts +1431 -526
  369. package/src/core/Events.ts +100 -112
  370. package/src/core/PersistenceManager.ts +103 -49
  371. package/src/core/PromptComposer.ts +158 -85
  372. package/src/core/ResponseEngine.ts +128 -46
  373. package/src/core/ResponsePipeline.ts +830 -0
  374. package/src/core/Route.ts +222 -53
  375. package/src/core/RoutingEngine.ts +345 -229
  376. package/src/core/SessionManager.ts +265 -0
  377. package/src/core/Step.ts +157 -67
  378. package/src/core/ToolExecutor.ts +52 -43
  379. package/src/index.ts +31 -37
  380. package/src/providers/AnthropicProvider.ts +71 -5
  381. package/src/providers/GeminiProvider.ts +83 -2
  382. package/src/providers/OpenAIProvider.ts +95 -3
  383. package/src/providers/OpenRouterProvider.ts +102 -2
  384. package/src/types/agent.ts +81 -46
  385. package/src/types/ai.ts +7 -0
  386. package/src/types/history.ts +91 -18
  387. package/src/types/index.ts +45 -7
  388. package/src/types/persistence.ts +45 -28
  389. package/src/types/route.ts +122 -57
  390. package/src/types/session.ts +20 -220
  391. package/src/types/template.ts +36 -0
  392. package/src/types/tool.ts +23 -19
  393. package/src/utils/clone.ts +36 -0
  394. package/src/utils/event.ts +1 -1
  395. package/src/utils/history.ts +143 -0
  396. package/src/utils/index.ts +53 -0
  397. package/src/utils/session.ts +204 -0
  398. package/src/utils/template.ts +335 -0
  399. package/dist/adapters/MemoryAdapter.d.ts.map +0 -1
  400. package/dist/adapters/MemoryAdapter.js.map +0 -1
  401. package/dist/adapters/MongoAdapter.d.ts.map +0 -1
  402. package/dist/adapters/MongoAdapter.js.map +0 -1
  403. package/dist/adapters/OpenSearchAdapter.d.ts.map +0 -1
  404. package/dist/adapters/OpenSearchAdapter.js.map +0 -1
  405. package/dist/adapters/PostgreSQLAdapter.d.ts.map +0 -1
  406. package/dist/adapters/PostgreSQLAdapter.js.map +0 -1
  407. package/dist/adapters/PrismaAdapter.d.ts.map +0 -1
  408. package/dist/adapters/PrismaAdapter.js.map +0 -1
  409. package/dist/adapters/RedisAdapter.d.ts.map +0 -1
  410. package/dist/adapters/RedisAdapter.js.map +0 -1
  411. package/dist/adapters/SQLiteAdapter.d.ts.map +0 -1
  412. package/dist/adapters/SQLiteAdapter.js.map +0 -1
  413. package/dist/adapters/index.d.ts.map +0 -1
  414. package/dist/adapters/index.js.map +0 -1
  415. package/dist/cjs/adapters/MemoryAdapter.d.ts.map +0 -1
  416. package/dist/cjs/adapters/MemoryAdapter.js.map +0 -1
  417. package/dist/cjs/adapters/MongoAdapter.d.ts.map +0 -1
  418. package/dist/cjs/adapters/MongoAdapter.js.map +0 -1
  419. package/dist/cjs/adapters/OpenSearchAdapter.d.ts.map +0 -1
  420. package/dist/cjs/adapters/OpenSearchAdapter.js.map +0 -1
  421. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +0 -1
  422. package/dist/cjs/adapters/PostgreSQLAdapter.js.map +0 -1
  423. package/dist/cjs/adapters/PrismaAdapter.d.ts.map +0 -1
  424. package/dist/cjs/adapters/PrismaAdapter.js.map +0 -1
  425. package/dist/cjs/adapters/RedisAdapter.d.ts.map +0 -1
  426. package/dist/cjs/adapters/RedisAdapter.js.map +0 -1
  427. package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +0 -1
  428. package/dist/cjs/adapters/SQLiteAdapter.js.map +0 -1
  429. package/dist/cjs/adapters/index.js.map +0 -1
  430. package/dist/cjs/constants/index.js.map +0 -1
  431. package/dist/cjs/core/Agent.d.ts +0 -197
  432. package/dist/cjs/core/Agent.d.ts.map +0 -1
  433. package/dist/cjs/core/Agent.js +0 -966
  434. package/dist/cjs/core/Agent.js.map +0 -1
  435. package/dist/cjs/core/DomainRegistry.d.ts +0 -36
  436. package/dist/cjs/core/DomainRegistry.d.ts.map +0 -1
  437. package/dist/cjs/core/DomainRegistry.js +0 -72
  438. package/dist/cjs/core/DomainRegistry.js.map +0 -1
  439. package/dist/cjs/core/Events.d.ts +0 -41
  440. package/dist/cjs/core/Events.d.ts.map +0 -1
  441. package/dist/cjs/core/Events.js +0 -99
  442. package/dist/cjs/core/Events.js.map +0 -1
  443. package/dist/cjs/core/PersistenceManager.d.ts.map +0 -1
  444. package/dist/cjs/core/PersistenceManager.js.map +0 -1
  445. package/dist/cjs/core/PromptComposer.d.ts +0 -24
  446. package/dist/cjs/core/PromptComposer.d.ts.map +0 -1
  447. package/dist/cjs/core/PromptComposer.js +0 -127
  448. package/dist/cjs/core/PromptComposer.js.map +0 -1
  449. package/dist/cjs/core/ResponseEngine.d.ts +0 -14
  450. package/dist/cjs/core/ResponseEngine.d.ts.map +0 -1
  451. package/dist/cjs/core/ResponseEngine.js +0 -56
  452. package/dist/cjs/core/ResponseEngine.js.map +0 -1
  453. package/dist/cjs/core/Route.d.ts +0 -90
  454. package/dist/cjs/core/Route.d.ts.map +0 -1
  455. package/dist/cjs/core/Route.js +0 -203
  456. package/dist/cjs/core/Route.js.map +0 -1
  457. package/dist/cjs/core/RoutingEngine.d.ts +0 -109
  458. package/dist/cjs/core/RoutingEngine.d.ts.map +0 -1
  459. package/dist/cjs/core/RoutingEngine.js.map +0 -1
  460. package/dist/cjs/core/Step.d.ts +0 -72
  461. package/dist/cjs/core/Step.d.ts.map +0 -1
  462. package/dist/cjs/core/Step.js +0 -150
  463. package/dist/cjs/core/Step.js.map +0 -1
  464. package/dist/cjs/core/Tool.d.ts +0 -39
  465. package/dist/cjs/core/Tool.d.ts.map +0 -1
  466. package/dist/cjs/core/Tool.js +0 -34
  467. package/dist/cjs/core/Tool.js.map +0 -1
  468. package/dist/cjs/core/ToolExecutor.d.ts +0 -29
  469. package/dist/cjs/core/ToolExecutor.d.ts.map +0 -1
  470. package/dist/cjs/core/ToolExecutor.js.map +0 -1
  471. package/dist/cjs/core/Transition.d.ts +0 -32
  472. package/dist/cjs/core/Transition.d.ts.map +0 -1
  473. package/dist/cjs/core/Transition.js +0 -89
  474. package/dist/cjs/core/Transition.js.map +0 -1
  475. package/dist/cjs/index.d.ts.map +0 -1
  476. package/dist/cjs/index.js.map +0 -1
  477. package/dist/cjs/providers/AnthropicProvider.d.ts.map +0 -1
  478. package/dist/cjs/providers/AnthropicProvider.js.map +0 -1
  479. package/dist/cjs/providers/GeminiProvider.js.map +0 -1
  480. package/dist/cjs/providers/OpenAIProvider.js.map +0 -1
  481. package/dist/cjs/providers/OpenRouterProvider.js.map +0 -1
  482. package/dist/cjs/providers/index.js.map +0 -1
  483. package/dist/cjs/types/agent.d.ts.map +0 -1
  484. package/dist/cjs/types/agent.js.map +0 -1
  485. package/dist/cjs/types/ai.d.ts.map +0 -1
  486. package/dist/cjs/types/history.d.ts.map +0 -1
  487. package/dist/cjs/types/history.js +0 -37
  488. package/dist/cjs/types/history.js.map +0 -1
  489. package/dist/cjs/types/index.d.ts +0 -12
  490. package/dist/cjs/types/index.d.ts.map +0 -1
  491. package/dist/cjs/types/index.js +0 -12
  492. package/dist/cjs/types/index.js.map +0 -1
  493. package/dist/cjs/types/persistence.d.ts.map +0 -1
  494. package/dist/cjs/types/persistence.js.map +0 -1
  495. package/dist/cjs/types/route.d.ts +0 -175
  496. package/dist/cjs/types/route.d.ts.map +0 -1
  497. package/dist/cjs/types/session.d.ts +0 -104
  498. package/dist/cjs/types/session.d.ts.map +0 -1
  499. package/dist/cjs/types/session.js.map +0 -1
  500. package/dist/cjs/types/tool.d.ts.map +0 -1
  501. package/dist/cjs/utils/event.js.map +0 -1
  502. package/dist/cjs/utils/id.js.map +0 -1
  503. package/dist/cjs/utils/logger.js.map +0 -1
  504. package/dist/cjs/utils/retry.js.map +0 -1
  505. package/dist/constants/index.d.ts.map +0 -1
  506. package/dist/constants/index.js.map +0 -1
  507. package/dist/core/Agent.d.ts +0 -197
  508. package/dist/core/Agent.d.ts.map +0 -1
  509. package/dist/core/Agent.js +0 -962
  510. package/dist/core/Agent.js.map +0 -1
  511. package/dist/core/DomainRegistry.d.ts +0 -36
  512. package/dist/core/DomainRegistry.d.ts.map +0 -1
  513. package/dist/core/DomainRegistry.js +0 -68
  514. package/dist/core/DomainRegistry.js.map +0 -1
  515. package/dist/core/Events.d.ts +0 -41
  516. package/dist/core/Events.d.ts.map +0 -1
  517. package/dist/core/Events.js +0 -94
  518. package/dist/core/Events.js.map +0 -1
  519. package/dist/core/PersistenceManager.d.ts.map +0 -1
  520. package/dist/core/PersistenceManager.js.map +0 -1
  521. package/dist/core/PromptComposer.d.ts +0 -24
  522. package/dist/core/PromptComposer.d.ts.map +0 -1
  523. package/dist/core/PromptComposer.js +0 -123
  524. package/dist/core/PromptComposer.js.map +0 -1
  525. package/dist/core/ResponseEngine.d.ts +0 -14
  526. package/dist/core/ResponseEngine.d.ts.map +0 -1
  527. package/dist/core/ResponseEngine.js +0 -52
  528. package/dist/core/ResponseEngine.js.map +0 -1
  529. package/dist/core/Route.d.ts +0 -90
  530. package/dist/core/Route.d.ts.map +0 -1
  531. package/dist/core/Route.js +0 -199
  532. package/dist/core/Route.js.map +0 -1
  533. package/dist/core/RoutingEngine.d.ts +0 -109
  534. package/dist/core/RoutingEngine.d.ts.map +0 -1
  535. package/dist/core/RoutingEngine.js.map +0 -1
  536. package/dist/core/Step.d.ts +0 -72
  537. package/dist/core/Step.d.ts.map +0 -1
  538. package/dist/core/Step.js +0 -146
  539. package/dist/core/Step.js.map +0 -1
  540. package/dist/core/Tool.d.ts +0 -39
  541. package/dist/core/Tool.d.ts.map +0 -1
  542. package/dist/core/Tool.js +0 -31
  543. package/dist/core/Tool.js.map +0 -1
  544. package/dist/core/ToolExecutor.d.ts +0 -29
  545. package/dist/core/ToolExecutor.d.ts.map +0 -1
  546. package/dist/core/ToolExecutor.js +0 -69
  547. package/dist/core/ToolExecutor.js.map +0 -1
  548. package/dist/core/Transition.d.ts +0 -32
  549. package/dist/core/Transition.d.ts.map +0 -1
  550. package/dist/core/Transition.js +0 -85
  551. package/dist/core/Transition.js.map +0 -1
  552. package/dist/index.d.ts.map +0 -1
  553. package/dist/index.js.map +0 -1
  554. package/dist/providers/AnthropicProvider.d.ts.map +0 -1
  555. package/dist/providers/AnthropicProvider.js.map +0 -1
  556. package/dist/providers/GeminiProvider.d.ts.map +0 -1
  557. package/dist/providers/GeminiProvider.js.map +0 -1
  558. package/dist/providers/OpenAIProvider.d.ts.map +0 -1
  559. package/dist/providers/OpenAIProvider.js.map +0 -1
  560. package/dist/providers/OpenRouterProvider.d.ts.map +0 -1
  561. package/dist/providers/OpenRouterProvider.js.map +0 -1
  562. package/dist/providers/index.d.ts.map +0 -1
  563. package/dist/providers/index.js.map +0 -1
  564. package/dist/types/agent.d.ts.map +0 -1
  565. package/dist/types/agent.js.map +0 -1
  566. package/dist/types/ai.d.ts.map +0 -1
  567. package/dist/types/ai.js.map +0 -1
  568. package/dist/types/history.d.ts.map +0 -1
  569. package/dist/types/history.js +0 -34
  570. package/dist/types/history.js.map +0 -1
  571. package/dist/types/index.d.ts +0 -12
  572. package/dist/types/index.d.ts.map +0 -1
  573. package/dist/types/index.js +0 -6
  574. package/dist/types/index.js.map +0 -1
  575. package/dist/types/persistence.d.ts.map +0 -1
  576. package/dist/types/persistence.js.map +0 -1
  577. package/dist/types/route.d.ts +0 -175
  578. package/dist/types/route.d.ts.map +0 -1
  579. package/dist/types/routing.d.ts.map +0 -1
  580. package/dist/types/schema.d.ts.map +0 -1
  581. package/dist/types/session.d.ts +0 -104
  582. package/dist/types/session.d.ts.map +0 -1
  583. package/dist/types/session.js.map +0 -1
  584. package/dist/types/tool.d.ts.map +0 -1
  585. package/dist/utils/event.d.ts.map +0 -1
  586. package/dist/utils/event.js.map +0 -1
  587. package/dist/utils/id.d.ts.map +0 -1
  588. package/dist/utils/id.js.map +0 -1
  589. package/dist/utils/logger.d.ts.map +0 -1
  590. package/dist/utils/logger.js.map +0 -1
  591. package/dist/utils/retry.d.ts.map +0 -1
  592. package/dist/utils/retry.js.map +0 -1
  593. package/docs/AGENT.md +0 -535
  594. package/docs/DOCS.md +0 -263
  595. package/docs/DOMAINS.md +0 -735
  596. package/docs/EXAMPLES.md +0 -467
  597. package/docs/GETTING_STARTED.md +0 -424
  598. package/docs/PERSISTENCE.md +0 -815
  599. package/docs/PROVIDERS.md +0 -612
  600. package/docs/ROUTES.md +0 -1085
  601. package/docs/STEPS.md +0 -883
  602. package/examples/business-onboarding.ts +0 -791
  603. package/examples/custom-database-persistence.ts +0 -574
  604. package/examples/declarative-agent.ts +0 -401
  605. package/examples/domain-scoping.ts +0 -366
  606. package/examples/healthcare-agent.ts +0 -511
  607. package/examples/redis-persistence.ts +0 -525
  608. package/examples/route-transitions.ts +0 -266
  609. package/examples/travel-agent.ts +0 -584
  610. package/src/core/DomainRegistry.ts +0 -80
  611. package/src/core/Tool.ts +0 -112
  612. package/src/core/Transition.ts +0 -115
  613. /package/dist/{adapters → cjs/src/adapters}/index.d.ts +0 -0
  614. /package/dist/cjs/{adapters → src/adapters}/index.js +0 -0
  615. /package/dist/cjs/{constants → src/constants}/index.d.ts +0 -0
  616. /package/dist/cjs/{constants → src/constants}/index.js +0 -0
  617. /package/dist/cjs/{providers → src/providers}/index.d.ts +0 -0
  618. /package/dist/cjs/{providers → src/providers}/index.js +0 -0
  619. /package/dist/cjs/{types → src/types}/agent.js +0 -0
  620. /package/dist/cjs/{types → src/types}/ai.js +0 -0
  621. /package/dist/cjs/{types → src/types}/persistence.js +0 -0
  622. /package/dist/cjs/{types → src/types}/route.js +0 -0
  623. /package/dist/cjs/{types → src/types}/routing.d.ts +0 -0
  624. /package/dist/cjs/{types → src/types}/routing.js +0 -0
  625. /package/dist/cjs/{types → src/types}/schema.d.ts +0 -0
  626. /package/dist/cjs/{types → src/types}/schema.js +0 -0
  627. /package/dist/cjs/{types → src/types}/tool.js +0 -0
  628. /package/dist/cjs/{utils → src/utils}/id.d.ts +0 -0
  629. /package/dist/cjs/{utils → src/utils}/id.js +0 -0
  630. /package/dist/cjs/{utils → src/utils}/logger.d.ts +0 -0
  631. /package/dist/cjs/{utils → src/utils}/logger.js +0 -0
  632. /package/dist/cjs/{utils → src/utils}/retry.d.ts +0 -0
  633. /package/dist/cjs/{utils → src/utils}/retry.js +0 -0
  634. /package/dist/{cjs → src}/adapters/index.d.ts +0 -0
  635. /package/dist/{cjs → src}/adapters/index.d.ts.map +0 -0
  636. /package/dist/{adapters → src/adapters}/index.js +0 -0
  637. /package/dist/{constants → src/constants}/index.d.ts +0 -0
  638. /package/dist/{cjs → src}/constants/index.d.ts.map +0 -0
  639. /package/dist/{constants → src/constants}/index.js +0 -0
  640. /package/dist/{providers → src/providers}/index.d.ts +0 -0
  641. /package/dist/{cjs → src}/providers/index.d.ts.map +0 -0
  642. /package/dist/{providers → src/providers}/index.js +0 -0
  643. /package/dist/{types → src/types}/agent.js +0 -0
  644. /package/dist/{types → src/types}/ai.js +0 -0
  645. /package/dist/{types → src/types}/persistence.js +0 -0
  646. /package/dist/{types → src/types}/route.js +0 -0
  647. /package/dist/{types → src/types}/routing.d.ts +0 -0
  648. /package/dist/{cjs → src}/types/routing.d.ts.map +0 -0
  649. /package/dist/{types → src/types}/routing.js +0 -0
  650. /package/dist/{cjs → src}/types/routing.js.map +0 -0
  651. /package/dist/{types → src/types}/schema.d.ts +0 -0
  652. /package/dist/{cjs → src}/types/schema.d.ts.map +0 -0
  653. /package/dist/{types → src/types}/schema.js +0 -0
  654. /package/dist/{cjs → src}/types/schema.js.map +0 -0
  655. /package/dist/{types → src/types}/tool.js +0 -0
  656. /package/dist/{utils → src/utils}/id.d.ts +0 -0
  657. /package/dist/{cjs → src}/utils/id.d.ts.map +0 -0
  658. /package/dist/{utils → src/utils}/id.js +0 -0
  659. /package/dist/{utils → src/utils}/logger.d.ts +0 -0
  660. /package/dist/{cjs → src}/utils/logger.d.ts.map +0 -0
  661. /package/dist/{utils → src/utils}/logger.js +0 -0
  662. /package/dist/{utils → src/utils}/retry.d.ts +0 -0
  663. /package/dist/{cjs → src}/utils/retry.d.ts.map +0 -0
  664. /package/dist/{utils → src/utils}/retry.js +0 -0
  665. /package/docs/{PUBLISHING.md → guides/advanced-patterns/publishing.md} +0 -0
@@ -1,14 +1,24 @@
1
- import type { Event } from "../types/history";
1
+ import type {
2
+ Event,
3
+ AgentOptions,
4
+ StructuredSchema,
5
+ RoutingDecision,
6
+ SessionState,
7
+ AiProvider,
8
+ } from "../types";
9
+ import { enterRoute, mergeCollected } from "../utils";
2
10
  import type { Route } from "./Route";
3
11
  import type { Step } from "./Step";
4
- import type { StructuredSchema } from "../types/schema";
5
- import type { RoutingDecision } from "../types/routing";
6
- import type { SessionState } from "../types/session";
7
- import type { AiProvider } from "../types/ai";
8
- import { enterRoute, mergeCollected } from "../types/session";
9
12
  import { PromptComposer } from "./PromptComposer";
10
13
  import { getLastMessageFromHistory } from "../utils/event";
11
14
  import { logger } from "../utils/logger";
15
+ import { render } from "../utils/template";
16
+ import { END_ROUTE_ID } from "../constants";
17
+
18
+ export interface CandidateStep<TContext = unknown, TData = unknown> {
19
+ step: Step<TContext, TData>;
20
+ isRouteComplete?: boolean;
21
+ }
12
22
 
13
23
  export interface RoutingDecisionOutput {
14
24
  context: string;
@@ -32,8 +42,33 @@ export interface RoutingEngineOptions {
32
42
  maxCandidates?: number;
33
43
  }
34
44
 
35
- export class RoutingEngine<TContext = unknown> {
36
- constructor(private readonly options?: RoutingEngineOptions) {}
45
+ export interface BuildStepSelectionPromptParams<
46
+ TContext = unknown,
47
+ TData = unknown
48
+ > {
49
+ route: Route<TContext, TData>;
50
+ currentStep: Step<TContext, TData> | undefined;
51
+ candidates: CandidateStep<TContext, TData>[];
52
+ data: Partial<TData>;
53
+ history: Event[];
54
+ lastMessage: string;
55
+ agentOptions?: AgentOptions<TContext, TData>;
56
+ context?: TContext;
57
+ session?: SessionState<TData>;
58
+ }
59
+
60
+ export interface BuildRoutingPromptParams<TContext = unknown, TData = unknown> {
61
+ history: Event[];
62
+ routes: Route<TContext, TData>[];
63
+ lastMessage: string;
64
+ agentOptions?: AgentOptions<TContext, TData>;
65
+ session?: SessionState<TData>;
66
+ activeRouteSteps?: Step<TContext, TData>[];
67
+ context?: TContext;
68
+ }
69
+
70
+ export class RoutingEngine<TContext = unknown, TData = unknown> {
71
+ constructor(private readonly options?: RoutingEngineOptions) { }
37
72
 
38
73
  /**
39
74
  * Optimized decision for single-route scenarios
@@ -41,31 +76,30 @@ export class RoutingEngine<TContext = unknown> {
41
76
  * @private
42
77
  */
43
78
  private async decideSingleRouteStep(params: {
44
- route: Route<TContext, unknown>;
45
- session: SessionState;
79
+ route: Route<TContext, TData>;
80
+ session: SessionState<TData>;
46
81
  history: Event[];
47
- agentMeta?: {
48
- name?: string;
49
- goal?: string;
50
- description?: string;
51
- personality?: string;
52
- };
82
+ agentOptions?: AgentOptions<TContext, TData>;
53
83
  provider: AiProvider;
54
84
  context: TContext;
55
85
  signal?: AbortSignal;
56
86
  }): Promise<{
57
- selectedRoute?: Route<TContext>;
58
- selectedStep?: Step<TContext>;
87
+ selectedRoute?: Route<TContext, TData>;
88
+ selectedStep?: Step<TContext, TData>;
59
89
  responseDirectives?: string[];
60
- session: SessionState;
90
+ session: SessionState<TData>;
61
91
  isRouteComplete?: boolean;
92
+ completedRoutes?: Route<TContext, TData>[];
62
93
  }> {
63
- const { route, session, history, agentMeta, provider, context, signal } =
94
+ const { route, session, history, agentOptions, provider, context, signal } =
64
95
  params;
65
96
 
66
97
  let updatedSession = session;
67
98
  const selectedRoute = route;
68
99
 
100
+ // Check if this single route is complete
101
+ const completedRoutes = route.isComplete(session.data || {}) ? [route] : [];
102
+
69
103
  // Enter route if not already in it
70
104
  if (!session.currentRoute || session.currentRoute.id !== route.id) {
71
105
  updatedSession = enterRoute(session, route.id, route.title);
@@ -109,6 +143,7 @@ export class RoutingEngine<TContext = unknown> {
109
143
  selectedStep: undefined,
110
144
  session: updatedSession,
111
145
  isRouteComplete: true,
146
+ completedRoutes,
112
147
  };
113
148
  } else {
114
149
  logger.debug(
@@ -119,24 +154,27 @@ export class RoutingEngine<TContext = unknown> {
119
154
  selectedStep: candidates[0].step,
120
155
  session: updatedSession,
121
156
  isRouteComplete: false,
157
+ completedRoutes,
122
158
  };
123
159
  }
124
160
  }
125
161
 
126
162
  // Multiple candidates - use AI to select best step
127
163
  const lastUserMessage = getLastMessageFromHistory(history);
128
- const stepPrompt = this.buildStepSelectionPrompt(
164
+ const stepPrompt = await this.buildStepSelectionPrompt({
129
165
  route,
130
166
  currentStep,
131
167
  candidates,
132
- updatedSession.data || {},
168
+ data: updatedSession.data || {},
133
169
  history,
134
- lastUserMessage,
135
- agentMeta
136
- );
170
+ lastMessage: lastUserMessage,
171
+ agentOptions,
172
+ context,
173
+ session: updatedSession,
174
+ });
137
175
 
138
176
  const stepSchema = this.buildStepSelectionSchema(
139
- candidates.map((c) => c.step.id)
177
+ candidates.map((c) => c.step)
140
178
  );
141
179
 
142
180
  const stepResult = await provider.generateMessage<
@@ -158,13 +196,11 @@ export class RoutingEngine<TContext = unknown> {
158
196
  });
159
197
 
160
198
  const selectedStepId = stepResult.structured?.selectedStepId;
161
- const selectedStep = candidates.find(
162
- (c) => c.step.id === selectedStepId
163
- )?.step;
199
+ const selectedStep = candidates.find((c) => c.step.id === selectedStepId);
164
200
 
165
201
  if (selectedStep) {
166
202
  logger.debug(
167
- `[RoutingEngine] Single-route: AI selected step: ${selectedStep.id}`
203
+ `[RoutingEngine] Single-route: AI selected step: ${selectedStep.step.id}`
168
204
  );
169
205
  logger.debug(
170
206
  `[RoutingEngine] Single-route: Reasoning: ${stepResult.structured?.reasoning}`
@@ -177,9 +213,10 @@ export class RoutingEngine<TContext = unknown> {
177
213
 
178
214
  return {
179
215
  selectedRoute,
180
- selectedStep: selectedStep || candidates[0].step,
216
+ selectedStep: selectedStep?.step || candidates[0].step,
181
217
  responseDirectives: stepResult.structured?.responseDirectives,
182
218
  session: updatedSession,
219
+ completedRoutes,
183
220
  };
184
221
  }
185
222
 
@@ -187,13 +224,12 @@ export class RoutingEngine<TContext = unknown> {
187
224
  * Recursively traverse step chain to find first non-skipped step or END_ROUTE
188
225
  * @private
189
226
  */
190
- private findFirstValidStepRecursive<TData = unknown>(
227
+ private findFirstValidStepRecursive(
191
228
  currentStep: Step<TContext, TData>,
192
229
  data: Partial<TData>,
193
230
  visited: Set<string>
194
231
  ): {
195
232
  step?: Step<TContext, TData>;
196
- condition?: string;
197
233
  isRouteComplete?: boolean;
198
234
  } {
199
235
  // Prevent infinite loops
@@ -205,14 +241,10 @@ export class RoutingEngine<TContext = unknown> {
205
241
  const transitions = currentStep.getTransitions();
206
242
 
207
243
  for (const transition of transitions) {
208
- const target = transition.getTarget();
244
+ const target = transition;
209
245
 
210
246
  // Check for END_ROUTE transition
211
- if (
212
- !target &&
213
- transition.spec.step &&
214
- typeof transition.spec.step === "symbol"
215
- ) {
247
+ if (target && target.id === END_ROUTE_ID) {
216
248
  // Found END_ROUTE - route is complete
217
249
  return {
218
250
  isRouteComplete: true,
@@ -228,7 +260,7 @@ export class RoutingEngine<TContext = unknown> {
228
260
  );
229
261
  return {
230
262
  step: target,
231
- condition: transition.condition,
263
+ isRouteComplete: false,
232
264
  };
233
265
  }
234
266
 
@@ -252,24 +284,12 @@ export class RoutingEngine<TContext = unknown> {
252
284
  * Identify valid next candidate steps based on current step and collected data
253
285
  * Returns step with isRouteComplete flag if route is complete (all steps skipped + has END_ROUTE transition)
254
286
  */
255
- getCandidateSteps<TData = unknown>(
287
+ getCandidateSteps(
256
288
  route: Route<TContext, TData>,
257
289
  currentStep: Step<TContext, TData> | undefined,
258
290
  data: Partial<TData>
259
- ): Array<{
260
- step: Step<TContext, TData>;
261
- condition?: string;
262
- requires?: string[];
263
- collectFields?: string[];
264
- isRouteComplete?: boolean;
265
- }> {
266
- const candidates: Array<{
267
- step: Step<TContext, TData>;
268
- condition?: string;
269
- requires?: string[];
270
- collectFields?: string[];
271
- isRouteComplete?: boolean;
272
- }> = [];
291
+ ): CandidateStep<TContext, TData>[] {
292
+ const candidates: CandidateStep<TContext, TData>[] = [];
273
293
 
274
294
  if (!currentStep) {
275
295
  const initialStep = route.initialStep;
@@ -286,28 +306,22 @@ export class RoutingEngine<TContext = unknown> {
286
306
  logger.debug(
287
307
  `[RoutingEngine] Route complete on entry: all steps skipped, END_ROUTE reached`
288
308
  );
289
- return [
290
- {
291
- step: initialStep,
292
- condition: "Route complete - all data collected on entry",
293
- isRouteComplete: true,
294
- },
295
- ];
309
+ candidates.push({
310
+ step: initialStep,
311
+ isRouteComplete: true,
312
+ });
296
313
  } else if (result.step) {
297
314
  // Found a non-skipped step
298
315
  candidates.push({
299
316
  step: result.step,
300
- condition: result.condition,
301
- requires: result.step.requires,
302
- collectFields: result.step.collectFields,
317
+ isRouteComplete: result.isRouteComplete || false,
303
318
  });
304
319
  }
305
320
  // If no step found and not complete, fall through to return empty candidates
306
321
  } else {
307
322
  candidates.push({
308
323
  step: initialStep,
309
- requires: initialStep.requires,
310
- collectFields: initialStep.collectFields,
324
+ isRouteComplete: false,
311
325
  });
312
326
  }
313
327
  return candidates;
@@ -317,14 +331,10 @@ export class RoutingEngine<TContext = unknown> {
317
331
  let hasEndRoute = false;
318
332
 
319
333
  for (const transition of transitions) {
320
- const target = transition.getTarget();
334
+ const target = transition;
321
335
 
322
336
  // Check for END_ROUTE transition (no target step)
323
- if (
324
- !target &&
325
- transition.spec.step &&
326
- typeof transition.spec.step === "symbol"
327
- ) {
337
+ if (target && target.id === END_ROUTE_ID) {
328
338
  hasEndRoute = true;
329
339
  continue;
330
340
  }
@@ -349,9 +359,7 @@ export class RoutingEngine<TContext = unknown> {
349
359
  // Found a non-skipped step deeper in the chain
350
360
  candidates.push({
351
361
  step: result.step,
352
- condition: result.condition || transition.condition,
353
- requires: result.step.requires,
354
- collectFields: result.step.collectFields,
362
+ isRouteComplete: result.isRouteComplete || false,
355
363
  });
356
364
  }
357
365
  continue;
@@ -359,9 +367,7 @@ export class RoutingEngine<TContext = unknown> {
359
367
 
360
368
  candidates.push({
361
369
  step: target,
362
- condition: transition.condition,
363
- requires: target.requires,
364
- collectFields: target.collectFields,
370
+ isRouteComplete: hasEndRoute || false,
365
371
  });
366
372
  }
367
373
 
@@ -376,7 +382,6 @@ export class RoutingEngine<TContext = unknown> {
376
382
  return [
377
383
  {
378
384
  step: currentStep,
379
- condition: "Route complete - all data collected",
380
385
  isRouteComplete: true,
381
386
  },
382
387
  ];
@@ -386,9 +391,7 @@ export class RoutingEngine<TContext = unknown> {
386
391
  if (!currentStep.shouldSkip(data)) {
387
392
  candidates.push({
388
393
  step: currentStep,
389
- condition: "Continue in current step (no valid transitions)",
390
- requires: currentStep.requires,
391
- collectFields: currentStep.collectFields,
394
+ isRouteComplete: hasEndRoute || false,
392
395
  });
393
396
  }
394
397
  }
@@ -401,59 +404,69 @@ export class RoutingEngine<TContext = unknown> {
401
404
  * and updates the session (including initialData merge when entering a new route).
402
405
  *
403
406
  * OPTIMIZATION: If there's only 1 route, skips route scoring and only does step selection.
407
+ * CROSS-ROUTE COMPLETION: Evaluates all routes for completion based on collected data.
404
408
  */
405
409
  async decideRouteAndStep(params: {
406
- routes: Route<TContext, unknown>[];
407
- session: SessionState;
410
+ routes: Route<TContext, TData>[];
411
+ session: SessionState<TData>;
408
412
  history: Event[];
409
- agentMeta?: {
410
- name?: string;
411
- goal?: string;
412
- description?: string;
413
- personality?: string;
414
- };
413
+ agentOptions?: AgentOptions<TContext, TData>;
415
414
  provider: AiProvider;
416
415
  context: TContext;
417
416
  signal?: AbortSignal;
418
417
  }): Promise<{
419
- selectedRoute?: Route<TContext>;
420
- selectedStep?: Step<TContext>;
418
+ selectedRoute?: Route<TContext, TData>;
419
+ selectedStep?: Step<TContext, TData>;
421
420
  responseDirectives?: string[];
422
- session: SessionState;
421
+ session: SessionState<TData>;
423
422
  isRouteComplete?: boolean;
423
+ completedRoutes?: Route<TContext, TData>[];
424
424
  }> {
425
- const { routes, session, history, agentMeta, provider, context, signal } =
426
- params;
425
+ const {
426
+ routes,
427
+ session,
428
+ history,
429
+ agentOptions,
430
+ provider,
431
+ context,
432
+ signal,
433
+ } = params;
427
434
 
428
435
  if (routes.length === 0) {
429
436
  return { session };
430
437
  }
431
438
 
439
+ // CROSS-ROUTE COMPLETION EVALUATION: Check all routes for completion
440
+ const completedRoutes = this.evaluateRouteCompletions(routes, session.data || {});
441
+
442
+ // Log completed routes
443
+ if (completedRoutes.length > 0) {
444
+ logger.debug(
445
+ `[RoutingEngine] Found ${completedRoutes.length} completed routes: ${completedRoutes.map(r => r.title).join(', ')}`
446
+ );
447
+ }
448
+
432
449
  // OPTIMIZATION: Single route - skip route scoring, only do step selection
433
450
  if (routes.length === 1) {
434
- return this.decideSingleRouteStep({
451
+ const result = await this.decideSingleRouteStep({
435
452
  route: routes[0],
436
453
  session,
437
454
  history,
438
- agentMeta,
455
+ agentOptions,
439
456
  provider,
440
457
  context,
441
458
  signal,
442
459
  });
460
+ return {
461
+ ...result,
462
+ completedRoutes,
463
+ };
443
464
  }
444
465
 
445
466
  const lastUserMessage = getLastMessageFromHistory(history);
446
467
 
447
- let activeRouteSteps:
448
- | Array<{
449
- stepId: string;
450
- description: string;
451
- condition?: string;
452
- requires?: string[];
453
- collectFields?: string[];
454
- }>
455
- | undefined;
456
- let activeRoute: Route<TContext> | undefined;
468
+ let activeRouteSteps: Step<TContext, TData>[] | undefined;
469
+ let activeRoute: Route<TContext, TData> | undefined;
457
470
  let isRouteComplete = false;
458
471
 
459
472
  if (session.currentRoute) {
@@ -477,13 +490,7 @@ export class RoutingEngine<TContext = unknown> {
477
490
  // Don't include steps in routing if route is complete
478
491
  activeRouteSteps = undefined;
479
492
  } else {
480
- activeRouteSteps = candidates.map((c) => ({
481
- stepId: c.step.id,
482
- description: c.step.description || "",
483
- condition: c.condition,
484
- requires: c.requires,
485
- collectFields: c.collectFields,
486
- }));
493
+ activeRouteSteps = candidates.map((c) => c.step);
487
494
  logger.debug(
488
495
  `[RoutingEngine] Found ${activeRouteSteps.length} candidate steps for active route`
489
496
  );
@@ -497,14 +504,15 @@ export class RoutingEngine<TContext = unknown> {
497
504
  activeRouteSteps
498
505
  );
499
506
 
500
- const routingPrompt = this.buildRoutingPrompt(
507
+ const routingPrompt = await this.buildRoutingPrompt({
501
508
  history,
502
509
  routes,
503
- lastUserMessage,
504
- agentMeta,
510
+ lastMessage: lastUserMessage,
511
+ agentOptions,
505
512
  session,
506
- activeRouteSteps
507
- );
513
+ activeRouteSteps,
514
+ context,
515
+ });
508
516
 
509
517
  const routingResult = await provider.generateMessage<
510
518
  TContext,
@@ -520,18 +528,29 @@ export class RoutingEngine<TContext = unknown> {
520
528
  },
521
529
  });
522
530
 
523
- let selectedRoute: Route<TContext> | undefined;
524
- let selectedStep: Step<TContext> | undefined;
531
+ let selectedRoute: Route<TContext, TData> | undefined;
532
+ let selectedStep: Step<TContext, TData> | undefined;
525
533
  let responseDirectives: string[] | undefined;
526
534
  let updatedSession = session;
527
535
 
528
536
  if (routingResult.structured?.routes) {
529
- const decision = this.decideRouteFromScores({
530
- context: routingResult.structured.context,
531
- routes: routingResult.structured.routes,
532
- responseDirectives: routingResult.structured.responseDirectives,
533
- });
534
- selectedRoute = routes.find((r) => r.id === decision.routeId);
537
+ // Use cross-route completion evaluation to select optimal route
538
+ const optimalRoute = this.selectOptimalRoute(
539
+ routes,
540
+ updatedSession.data || {},
541
+ routingResult.structured.routes
542
+ );
543
+
544
+ // Fall back to traditional scoring if no optimal route found
545
+ selectedRoute = optimalRoute || (() => {
546
+ const decision = this.decideRouteFromScores({
547
+ context: routingResult.structured.context,
548
+ routes: routingResult.structured.routes,
549
+ responseDirectives: routingResult.structured.responseDirectives,
550
+ });
551
+ return routes.find((r) => r.id === decision.routeId);
552
+ })();
553
+
535
554
  responseDirectives = routingResult.structured.responseDirectives;
536
555
 
537
556
  if (
@@ -584,104 +603,175 @@ export class RoutingEngine<TContext = unknown> {
584
603
  responseDirectives,
585
604
  session: updatedSession,
586
605
  isRouteComplete,
606
+ completedRoutes,
587
607
  };
588
608
  }
589
609
 
610
+ /**
611
+ * Evaluate all routes for completion based on collected data
612
+ * @param routes - All available routes
613
+ * @param data - Currently collected agent-level data
614
+ * @returns Array of routes that are complete
615
+ */
616
+ evaluateRouteCompletions(routes: Route<TContext, TData>[], data: Partial<TData>): Route<TContext, TData>[] {
617
+ return routes.filter(route => route.isComplete(data));
618
+ }
619
+
620
+ /**
621
+ * Get completion status for all routes
622
+ * @param routes - All available routes
623
+ * @param data - Currently collected agent-level data
624
+ * @returns Map of route ID to completion progress (0-1)
625
+ */
626
+ getRouteCompletionStatus(routes: Route<TContext, TData>[], data: Partial<TData>): Map<string, number> {
627
+ const completionStatus = new Map<string, number>();
628
+
629
+ for (const route of routes) {
630
+ const progress = route.getCompletionProgress(data);
631
+ completionStatus.set(route.id, progress);
632
+ }
633
+
634
+ return completionStatus;
635
+ }
636
+
637
+ /**
638
+ * Find the best route to continue based on completion status and user intent
639
+ * Prioritizes routes that are partially complete but not finished
640
+ * @param routes - All available routes
641
+ * @param data - Currently collected agent-level data
642
+ * @param routeScores - AI-generated route scores from routing decision
643
+ * @returns Route that should be prioritized for continuation
644
+ */
645
+ selectOptimalRoute(
646
+ routes: Route<TContext, TData>[],
647
+ data: Partial<TData>,
648
+ routeScores: Record<string, number>
649
+ ): Route<TContext, TData> | undefined {
650
+ const completionStatus = this.getRouteCompletionStatus(routes, data);
651
+
652
+ // Create weighted scores combining AI intent scores with completion progress
653
+ const weightedScores: Array<{ route: Route<TContext, TData>; score: number }> = [];
654
+
655
+ for (const route of routes) {
656
+ const aiScore = routeScores[route.id] || 0;
657
+ const completionProgress = completionStatus.get(route.id) || 0;
658
+
659
+ // Skip fully completed routes unless they have very high AI scores
660
+ if (completionProgress >= 1.0 && aiScore < 80) {
661
+ continue;
662
+ }
663
+
664
+ // Boost partially complete routes that match user intent
665
+ let weightedScore = aiScore;
666
+ if (completionProgress > 0 && completionProgress < 1.0) {
667
+ // Boost score for partially complete routes
668
+ weightedScore += (completionProgress * 20); // Up to 20 point boost
669
+ }
670
+
671
+ weightedScores.push({ route, score: weightedScore });
672
+ }
673
+
674
+ // Sort by weighted score and return the best option
675
+ weightedScores.sort((a, b) => b.score - a.score);
676
+
677
+ if (weightedScores.length > 0) {
678
+ logger.debug(
679
+ `[RoutingEngine] Selected optimal route: ${weightedScores[0].route.title} ` +
680
+ `(AI: ${routeScores[weightedScores[0].route.id]}, ` +
681
+ `Completion: ${(completionStatus.get(weightedScores[0].route.id) || 0) * 100}%, ` +
682
+ `Weighted: ${weightedScores[0].score})`
683
+ );
684
+ return weightedScores[0].route;
685
+ }
686
+
687
+ return undefined;
688
+ }
689
+
590
690
  /**
591
691
  * Build prompt for step selection within a single route
592
692
  * @private
593
693
  */
594
- private buildStepSelectionPrompt(
595
- route: Route<TContext>,
596
- currentStep: Step<TContext> | undefined,
597
- candidates: Array<{
598
- step: Step<TContext>;
599
- condition?: string;
600
- requires?: string[];
601
- collectFields?: string[];
602
- }>,
603
- data: Partial<unknown>,
604
- history: Event[],
605
- lastMessage: string,
606
- agentMeta?: {
607
- name?: string;
608
- goal?: string;
609
- description?: string;
610
- personality?: string;
611
- }
612
- ): string {
613
- const pc = new PromptComposer();
694
+ private async buildStepSelectionPrompt(
695
+ params: BuildStepSelectionPromptParams<TContext, TData>
696
+ ): Promise<string> {
697
+ const {
698
+ route,
699
+ currentStep,
700
+ candidates,
701
+ data,
702
+ history,
703
+ lastMessage,
704
+ agentOptions,
705
+ context,
706
+ session,
707
+ } = params;
708
+ const templateContext = { context, session, history };
709
+ const pc = new PromptComposer<TContext, TData>(templateContext);
614
710
 
615
711
  // Add agent metadata
616
- if (agentMeta?.name || agentMeta?.goal || agentMeta?.description) {
617
- pc.addAgentMeta({
618
- name: agentMeta?.name || "Agent",
619
- description: agentMeta?.description,
620
- goal: agentMeta?.goal,
621
- });
712
+ if (agentOptions) {
713
+ await pc.addAgentMeta(agentOptions);
622
714
  }
623
715
 
624
- const personality =
625
- agentMeta?.personality || "Tone: brief, natural, 1-2 short sentences.";
626
- pc.addPersonality(personality);
627
-
628
716
  // Add route context
629
- pc.addInstruction(
717
+ await pc.addInstruction(
630
718
  `Active Route: ${route.title}\nDescription: ${route.description || "N/A"}`
631
719
  );
632
720
 
633
721
  // Add current step context
634
722
  if (currentStep) {
635
- pc.addInstruction(
636
- `Current Step: ${currentStep.id}\nDescription: ${
637
- currentStep.description || "N/A"
723
+ await pc.addInstruction(
724
+ `Current Step: ${currentStep.id}\nDescription: ${currentStep.description || "N/A"
638
725
  }`
639
726
  );
640
727
  } else {
641
- pc.addInstruction("Current Step: None (entering route)");
728
+ await pc.addInstruction("Current Step: None (entering route)");
642
729
  }
643
730
 
644
731
  // Add collected data context
645
732
  if (Object.keys(data).length > 0) {
646
- pc.addInstruction(
733
+ await pc.addInstruction(
647
734
  `Collected Data So Far:\n${JSON.stringify(data, null, 2)}`
648
735
  );
649
736
  } else {
650
- pc.addInstruction("Collected Data: None yet");
737
+ await pc.addInstruction("Collected Data: None yet");
651
738
  }
652
739
 
653
740
  // Add conversation history
654
- pc.addInteractionHistory(history);
655
- pc.addLastMessage(lastMessage);
741
+ await pc.addInteractionHistory(history);
742
+ await pc.addLastMessage(lastMessage);
656
743
 
657
744
  // Add candidate steps
658
- const stepDescriptions = candidates.map((candidate, idx) => {
745
+ const stepDescriptions = [];
746
+ for (const candidate of candidates) {
747
+ const idx = candidates.indexOf(candidate);
659
748
  const parts = [
660
749
  `${idx + 1}. Step ID: ${candidate.step.id}`,
661
750
  ` Description: ${candidate.step.description || "N/A"}`,
662
751
  ];
663
752
 
664
- if (candidate.condition) {
665
- parts.push(` Condition: ${candidate.condition}`);
753
+ if (candidate.step.when) {
754
+ const renderedWhen = await render(candidate.step.when, templateContext);
755
+ parts.push(` When this step should be completed: ${renderedWhen}`);
666
756
  }
667
757
 
668
- if (candidate.requires && candidate.requires.length > 0) {
669
- parts.push(` Required Data: ${candidate.requires.join(", ")}`);
758
+ if (candidate.step.requires && candidate.step.requires.length > 0) {
759
+ parts.push(` Required Data: ${candidate.step.requires.join(", ")}`);
670
760
  }
671
761
 
672
- if (candidate.collectFields && candidate.collectFields.length > 0) {
673
- parts.push(` Collects: ${candidate.collectFields.join(", ")}`);
762
+ if (candidate.step.collect && candidate.step.collect.length > 0) {
763
+ parts.push(` Collects: ${candidate.step.collect.join(", ")}`);
674
764
  }
675
765
 
676
- return parts.join("\n");
677
- });
766
+ stepDescriptions.push(parts.join("\n"));
767
+ }
678
768
 
679
- pc.addInstruction(
769
+ await pc.addInstruction(
680
770
  `Available Steps to Transition To:\n${stepDescriptions.join("\n\n")}`
681
771
  );
682
772
 
683
- // Add decision instructions
684
- pc.addInstruction(
773
+ // Add decision prompt
774
+ await pc.addInstruction(
685
775
  [
686
776
  "Task: Decide which step to transition to based on:",
687
777
  "1. The user's current message and intent",
@@ -707,7 +797,9 @@ export class RoutingEngine<TContext = unknown> {
707
797
  * Build schema for step selection
708
798
  * @private
709
799
  */
710
- private buildStepSelectionSchema(validStepIds: string[]): StructuredSchema {
800
+ private buildStepSelectionSchema(
801
+ validSteps: Step<TContext, TData>[]
802
+ ): StructuredSchema {
711
803
  return {
712
804
  description:
713
805
  "Step transition decision based on conversation context and collected data",
@@ -722,7 +814,7 @@ export class RoutingEngine<TContext = unknown> {
722
814
  type: "string",
723
815
  nullable: false,
724
816
  description: "The ID of the selected step to transition to",
725
- enum: validStepIds,
817
+ enum: validSteps.map((s) => s.id),
726
818
  },
727
819
  responseDirectives: {
728
820
  type: "array",
@@ -737,9 +829,9 @@ export class RoutingEngine<TContext = unknown> {
737
829
  }
738
830
 
739
831
  buildDynamicRoutingSchema(
740
- routes: Route<TContext>[],
832
+ routes: Route<TContext, TData>[],
741
833
  extrasSchema?: StructuredSchema,
742
- activeRouteSteps?: { stepId: string; description: string }[]
834
+ activeRouteSteps?: Step<TContext, TData>[]
743
835
  ): StructuredSchema {
744
836
  const routeIds = routes.map((r) => r.id);
745
837
  const routeProperties: Record<string, StructuredSchema> = {};
@@ -789,7 +881,7 @@ export class RoutingEngine<TContext = unknown> {
789
881
  nullable: false,
790
882
  description:
791
883
  "The step ID to transition to within the active route (required if continuing in current route)",
792
- enum: activeRouteSteps.map((s) => s.stepId),
884
+ enum: activeRouteSteps.map((s) => s.id),
793
885
  };
794
886
  base.properties.stepReasoning = {
795
887
  type: "string",
@@ -811,37 +903,24 @@ export class RoutingEngine<TContext = unknown> {
811
903
  return base;
812
904
  }
813
905
 
814
- buildRoutingPrompt(
815
- history: Event[],
816
- routes: Route<TContext>[],
817
- lastMessage: string,
818
- agentMeta?: {
819
- name?: string;
820
- goal?: string;
821
- description?: string;
822
- personality?: string;
823
- },
824
- session?: SessionState,
825
- activeRouteSteps?: Array<{
826
- stepId: string;
827
- description: string;
828
- condition?: string;
829
- requires?: string[];
830
- collectFields?: string[];
831
- }>
832
- ): string {
833
- const pc = new PromptComposer();
834
- if (agentMeta?.name || agentMeta?.goal || agentMeta?.description) {
835
- pc.addAgentMeta({
836
- name: agentMeta?.name || "Agent",
837
- description: agentMeta?.description,
838
- goal: agentMeta?.goal,
839
- });
906
+ async buildRoutingPrompt(
907
+ params: BuildRoutingPromptParams<TContext, TData>
908
+ ): Promise<string> {
909
+ const {
910
+ history,
911
+ routes,
912
+ lastMessage,
913
+ agentOptions,
914
+ session,
915
+ activeRouteSteps,
916
+ context,
917
+ } = params;
918
+ const templateContext = { context, session, history };
919
+ const pc = new PromptComposer<TContext, TData>(templateContext);
920
+ if (agentOptions) {
921
+ await pc.addAgentMeta(agentOptions);
840
922
  }
841
- const personality =
842
- agentMeta?.personality || "Tone: brief, natural, 1-2 short sentences.";
843
- pc.addPersonality(personality);
844
- pc.addInstruction(
923
+ await pc.addInstruction(
845
924
  "Task: Intent analysis and route scoring (0-100). Score ALL listed routes."
846
925
  );
847
926
 
@@ -863,7 +942,42 @@ export class RoutingEngine<TContext = unknown> {
863
942
  sessionInfo.push(
864
943
  "Note: User is mid-conversation. They may want to continue current route or switch to a new one based on their intent."
865
944
  );
866
- pc.addInstruction(sessionInfo.join("\n"));
945
+ await pc.addInstruction(sessionInfo.join("\n"));
946
+
947
+ // Add cross-route completion status
948
+ const completionStatus = this.getRouteCompletionStatus(routes, session.data || {});
949
+ const completedRoutes = this.evaluateRouteCompletions(routes, session.data || {});
950
+
951
+ if (completionStatus.size > 0) {
952
+ const statusInfo = [
953
+ "",
954
+ "Route completion status based on collected data:",
955
+ ];
956
+
957
+ for (const route of routes) {
958
+ const progress = completionStatus.get(route.id) || 0;
959
+ const isComplete = completedRoutes.includes(route);
960
+ const progressPercent = Math.round(progress * 100);
961
+
962
+ statusInfo.push(
963
+ `- ${route.title}: ${progressPercent}% complete${isComplete ? ' ✓ COMPLETE' : ''}`
964
+ );
965
+
966
+ if (!isComplete && route.requiredFields) {
967
+ const missingFields = route.getMissingRequiredFields(session.data || {});
968
+ if (missingFields.length > 0) {
969
+ statusInfo.push(` Missing: ${missingFields.join(', ')}`);
970
+ }
971
+ }
972
+ }
973
+
974
+ statusInfo.push(
975
+ "",
976
+ "Consider route completion status when scoring. Partially complete routes may be good candidates for continuation."
977
+ );
978
+
979
+ await pc.addInstruction(statusInfo.join("\n"));
980
+ }
867
981
 
868
982
  // Add available steps for the active route
869
983
  if (activeRouteSteps && activeRouteSteps.length > 0) {
@@ -871,21 +985,25 @@ export class RoutingEngine<TContext = unknown> {
871
985
  "",
872
986
  "Available steps in active route (choose one to transition to):",
873
987
  ];
874
- activeRouteSteps.forEach((step, idx) => {
875
- stepInfo.push(`${idx + 1}. Step: ${step.stepId}`);
988
+ for (const step of activeRouteSteps) {
989
+ const idx = activeRouteSteps.indexOf(step);
990
+ stepInfo.push(`${idx + 1}. Step: ${step.id}`);
876
991
  if (step.description) {
877
992
  stepInfo.push(` Description: ${step.description}`);
878
993
  }
879
- if (step.condition) {
880
- stepInfo.push(` Condition: ${step.condition}`);
994
+ const renderedWhen = await render(step.when, templateContext);
995
+ if (step.when) {
996
+ stepInfo.push(
997
+ ` When this step should be completed: ${renderedWhen}`
998
+ );
881
999
  }
882
1000
  if (step.requires && step.requires.length > 0) {
883
1001
  stepInfo.push(` Required data: ${step.requires.join(", ")}`);
884
1002
  }
885
- if (step.collectFields && step.collectFields.length > 0) {
886
- stepInfo.push(` Will collect: ${step.collectFields.join(", ")}`);
1003
+ if (step.collect && step.collect.length > 0) {
1004
+ stepInfo.push(` Will collect: ${step.collect.join(", ")}`);
887
1005
  }
888
- });
1006
+ }
889
1007
  stepInfo.push("");
890
1008
  stepInfo.push(
891
1009
  "IMPORTANT: You MUST select a step to transition to. Evaluate which step makes the most sense based on:"
@@ -894,16 +1012,14 @@ export class RoutingEngine<TContext = unknown> {
894
1012
  stepInfo.push("- What data is still needed vs already present");
895
1013
  stepInfo.push("- The logical next step in the conversation");
896
1014
  stepInfo.push("- Whether conditions for steps are met");
897
- pc.addInstruction(stepInfo.join("\n"));
1015
+ await pc.addInstruction(stepInfo.join("\n"));
898
1016
  }
899
1017
  }
900
1018
 
901
- pc.addInteractionHistory(history);
902
- pc.addLastMessage(lastMessage);
903
- // Cast to unknown to satisfy generic constraints in composer
904
- // This is safe because PromptComposer only reads route metadata (id, title, description)
905
- pc.addRoutingOverview(routes as unknown as Route<unknown>[]);
906
- pc.addInstruction(
1019
+ await pc.addInteractionHistory(history);
1020
+ await pc.addLastMessage(lastMessage);
1021
+ await pc.addRoutingOverview(routes);
1022
+ await pc.addInstruction(
907
1023
  [
908
1024
  "Scoring rules:",
909
1025
  "- 90-100: explicit keywords + clear intent",