@falai/agent 0.9.2 → 1.0.1

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 (628) hide show
  1. package/README.md +281 -42
  2. package/dist/adapters/MemoryAdapter.d.ts.map +1 -0
  3. package/dist/adapters/MemoryAdapter.js.map +1 -0
  4. package/dist/adapters/MongoAdapter.d.ts.map +1 -0
  5. package/dist/adapters/MongoAdapter.js.map +1 -0
  6. package/dist/adapters/OpenSearchAdapter.d.ts.map +1 -0
  7. package/dist/adapters/OpenSearchAdapter.js.map +1 -0
  8. package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -0
  9. package/dist/adapters/PostgreSQLAdapter.js.map +1 -0
  10. package/dist/adapters/PrismaAdapter.d.ts.map +1 -0
  11. package/dist/{src/adapters → adapters}/PrismaAdapter.js +3 -2
  12. package/dist/adapters/PrismaAdapter.js.map +1 -0
  13. package/dist/adapters/RedisAdapter.d.ts.map +1 -0
  14. package/dist/{src/adapters → adapters}/RedisAdapter.js +3 -3
  15. package/dist/adapters/RedisAdapter.js.map +1 -0
  16. package/dist/adapters/SQLiteAdapter.d.ts.map +1 -0
  17. package/dist/adapters/SQLiteAdapter.js.map +1 -0
  18. package/dist/adapters/index.d.ts.map +1 -0
  19. package/dist/adapters/index.js.map +1 -0
  20. package/dist/cjs/adapters/MemoryAdapter.js.map +1 -0
  21. package/dist/cjs/adapters/MongoAdapter.js.map +1 -0
  22. package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -0
  23. package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -0
  24. package/dist/{src → cjs}/adapters/PrismaAdapter.d.ts.map +1 -1
  25. package/dist/cjs/{src/adapters → adapters}/PrismaAdapter.js +3 -2
  26. package/dist/cjs/adapters/PrismaAdapter.js.map +1 -0
  27. package/dist/cjs/{src/adapters → adapters}/RedisAdapter.js +2 -2
  28. package/dist/cjs/adapters/RedisAdapter.js.map +1 -0
  29. package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -0
  30. package/dist/cjs/adapters/index.js.map +1 -0
  31. package/dist/cjs/constants/index.js.map +1 -0
  32. package/dist/cjs/{src/core → core}/Agent.d.ts +16 -1
  33. package/dist/cjs/core/Agent.d.ts.map +1 -0
  34. package/dist/cjs/{src/core → core}/Agent.js +63 -2
  35. package/dist/cjs/core/Agent.js.map +1 -0
  36. package/dist/cjs/core/BatchExecutor.d.ts +353 -0
  37. package/dist/cjs/core/BatchExecutor.d.ts.map +1 -0
  38. package/dist/cjs/core/BatchExecutor.js +850 -0
  39. package/dist/cjs/core/BatchExecutor.js.map +1 -0
  40. package/dist/cjs/core/BatchPromptBuilder.d.ts +86 -0
  41. package/dist/cjs/core/BatchPromptBuilder.d.ts.map +1 -0
  42. package/dist/cjs/core/BatchPromptBuilder.js +217 -0
  43. package/dist/cjs/core/BatchPromptBuilder.js.map +1 -0
  44. package/dist/cjs/core/Events.js.map +1 -0
  45. package/dist/cjs/core/PersistenceManager.js.map +1 -0
  46. package/dist/{src → cjs}/core/PromptComposer.d.ts +1 -1
  47. package/dist/cjs/core/PromptComposer.d.ts.map +1 -0
  48. package/dist/cjs/{src/core → core}/PromptComposer.js +44 -7
  49. package/dist/cjs/core/PromptComposer.js.map +1 -0
  50. package/dist/{src → cjs}/core/ResponseEngine.d.ts.map +1 -1
  51. package/dist/cjs/core/ResponseEngine.js +211 -0
  52. package/dist/cjs/core/ResponseEngine.js.map +1 -0
  53. package/dist/{src → cjs}/core/ResponseModal.d.ts +45 -0
  54. package/dist/cjs/core/ResponseModal.d.ts.map +1 -0
  55. package/dist/cjs/{src/core → core}/ResponseModal.js +752 -74
  56. package/dist/cjs/core/ResponseModal.js.map +1 -0
  57. package/dist/{src → cjs}/core/ResponsePipeline.d.ts +2 -2
  58. package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -0
  59. package/dist/cjs/{src/core → core}/ResponsePipeline.js +13 -6
  60. package/dist/cjs/core/ResponsePipeline.js.map +1 -0
  61. package/dist/{src → cjs}/core/Route.d.ts +34 -5
  62. package/dist/cjs/core/Route.d.ts.map +1 -0
  63. package/dist/cjs/{src/core → core}/Route.js +196 -19
  64. package/dist/cjs/core/Route.js.map +1 -0
  65. package/dist/cjs/{src/core → core}/RoutingEngine.d.ts +30 -5
  66. package/dist/cjs/core/RoutingEngine.d.ts.map +1 -0
  67. package/dist/cjs/{src/core → core}/RoutingEngine.js +330 -80
  68. package/dist/cjs/core/RoutingEngine.js.map +1 -0
  69. package/dist/cjs/core/SessionManager.js.map +1 -0
  70. package/dist/{src → cjs}/core/Step.d.ts +31 -10
  71. package/dist/cjs/core/Step.d.ts.map +1 -0
  72. package/dist/cjs/{src/core → core}/Step.js +105 -10
  73. package/dist/cjs/core/Step.js.map +1 -0
  74. package/dist/cjs/core/ToolManager.js.map +1 -0
  75. package/dist/{src → cjs}/index.d.ts +4 -1
  76. package/dist/cjs/index.d.ts.map +1 -0
  77. package/dist/cjs/{src/index.js → index.js} +12 -1
  78. package/dist/cjs/index.js.map +1 -0
  79. package/dist/cjs/{src/providers → providers}/AnthropicProvider.js +18 -18
  80. package/dist/cjs/providers/AnthropicProvider.js.map +1 -0
  81. package/dist/{src → cjs}/providers/GeminiProvider.d.ts.map +1 -1
  82. package/dist/cjs/{src/providers → providers}/GeminiProvider.js +123 -51
  83. package/dist/cjs/providers/GeminiProvider.js.map +1 -0
  84. package/dist/cjs/{src/providers → providers}/OpenAIProvider.js +19 -19
  85. package/dist/cjs/providers/OpenAIProvider.js.map +1 -0
  86. package/dist/cjs/{src/providers → providers}/OpenRouterProvider.js +19 -19
  87. package/dist/cjs/providers/OpenRouterProvider.js.map +1 -0
  88. package/dist/cjs/providers/index.js.map +1 -0
  89. package/dist/cjs/{src/types → types}/agent.d.ts +15 -3
  90. package/dist/cjs/types/agent.d.ts.map +1 -0
  91. package/dist/cjs/types/agent.js.map +1 -0
  92. package/dist/{src → cjs}/types/ai.js.map +1 -1
  93. package/dist/cjs/types/history.js.map +1 -0
  94. package/dist/cjs/{src/types → types}/index.d.ts +2 -1
  95. package/dist/{src → cjs}/types/index.d.ts.map +1 -1
  96. package/dist/cjs/{src/types → types}/index.js +6 -1
  97. package/dist/cjs/types/index.js.map +1 -0
  98. package/dist/cjs/types/persistence.js.map +1 -0
  99. package/dist/cjs/{src/types → types}/route.d.ts +111 -12
  100. package/dist/cjs/types/route.d.ts.map +1 -0
  101. package/dist/cjs/{src/types → types}/route.js.map +1 -1
  102. package/dist/cjs/types/session.js.map +1 -0
  103. package/dist/cjs/types/template.d.ts +88 -0
  104. package/dist/cjs/types/template.d.ts.map +1 -0
  105. package/dist/cjs/types/tool.js.map +1 -0
  106. package/dist/cjs/utils/clone.js.map +1 -0
  107. package/dist/cjs/utils/condition.d.ts +38 -0
  108. package/dist/cjs/utils/condition.d.ts.map +1 -0
  109. package/dist/cjs/utils/condition.js +168 -0
  110. package/dist/cjs/utils/condition.js.map +1 -0
  111. package/dist/cjs/utils/event.js.map +1 -0
  112. package/dist/cjs/utils/history.js.map +1 -0
  113. package/dist/cjs/utils/id.js.map +1 -0
  114. package/dist/cjs/{src/utils → utils}/index.d.ts +3 -1
  115. package/dist/cjs/utils/index.d.ts.map +1 -0
  116. package/dist/cjs/{src/utils → utils}/index.js +12 -1
  117. package/dist/cjs/utils/index.js.map +1 -0
  118. package/dist/cjs/utils/json.d.ts +16 -0
  119. package/dist/cjs/utils/json.d.ts.map +1 -0
  120. package/dist/cjs/utils/json.js +47 -0
  121. package/dist/cjs/utils/json.js.map +1 -0
  122. package/dist/cjs/utils/logger.js.map +1 -0
  123. package/dist/{src → cjs}/utils/retry.d.ts +0 -3
  124. package/dist/cjs/utils/retry.d.ts.map +1 -0
  125. package/dist/cjs/{src/utils → utils}/retry.js +8 -7
  126. package/dist/cjs/utils/retry.js.map +1 -0
  127. package/dist/cjs/utils/session.js.map +1 -0
  128. package/dist/{src → cjs}/utils/template.d.ts +48 -0
  129. package/dist/cjs/utils/template.d.ts.map +1 -0
  130. package/dist/cjs/{src/utils → utils}/template.js +100 -0
  131. package/dist/cjs/utils/template.js.map +1 -0
  132. package/dist/constants/index.d.ts.map +1 -0
  133. package/dist/constants/index.js.map +1 -0
  134. package/dist/{src/core → core}/Agent.d.ts +16 -1
  135. package/dist/core/Agent.d.ts.map +1 -0
  136. package/dist/{src/core → core}/Agent.js +64 -3
  137. package/dist/core/Agent.js.map +1 -0
  138. package/dist/core/BatchExecutor.d.ts +353 -0
  139. package/dist/core/BatchExecutor.d.ts.map +1 -0
  140. package/dist/core/BatchExecutor.js +845 -0
  141. package/dist/core/BatchExecutor.js.map +1 -0
  142. package/dist/core/BatchPromptBuilder.d.ts +86 -0
  143. package/dist/core/BatchPromptBuilder.d.ts.map +1 -0
  144. package/dist/core/BatchPromptBuilder.js +213 -0
  145. package/dist/core/BatchPromptBuilder.js.map +1 -0
  146. package/dist/core/Events.d.ts.map +1 -0
  147. package/dist/core/Events.js.map +1 -0
  148. package/dist/core/PersistenceManager.d.ts.map +1 -0
  149. package/dist/core/PersistenceManager.js.map +1 -0
  150. package/dist/{cjs/src/core → core}/PromptComposer.d.ts +1 -1
  151. package/dist/core/PromptComposer.d.ts.map +1 -0
  152. package/dist/{src/core → core}/PromptComposer.js +45 -8
  153. package/dist/core/PromptComposer.js.map +1 -0
  154. package/dist/core/ResponseEngine.d.ts.map +1 -0
  155. package/dist/core/ResponseEngine.js +207 -0
  156. package/dist/core/ResponseEngine.js.map +1 -0
  157. package/dist/{cjs/src/core → core}/ResponseModal.d.ts +45 -0
  158. package/dist/core/ResponseModal.d.ts.map +1 -0
  159. package/dist/{src/core → core}/ResponseModal.js +752 -74
  160. package/dist/core/ResponseModal.js.map +1 -0
  161. package/dist/{cjs/src/core → core}/ResponsePipeline.d.ts +2 -2
  162. package/dist/core/ResponsePipeline.d.ts.map +1 -0
  163. package/dist/{src/core → core}/ResponsePipeline.js +13 -6
  164. package/dist/core/ResponsePipeline.js.map +1 -0
  165. package/dist/{cjs/src/core → core}/Route.d.ts +34 -5
  166. package/dist/core/Route.d.ts.map +1 -0
  167. package/dist/{src/core → core}/Route.js +195 -18
  168. package/dist/core/Route.js.map +1 -0
  169. package/dist/{src/core → core}/RoutingEngine.d.ts +30 -5
  170. package/dist/core/RoutingEngine.d.ts.map +1 -0
  171. package/dist/{src/core → core}/RoutingEngine.js +310 -60
  172. package/dist/core/RoutingEngine.js.map +1 -0
  173. package/dist/core/SessionManager.d.ts.map +1 -0
  174. package/dist/core/SessionManager.js.map +1 -0
  175. package/dist/{cjs/src/core → core}/Step.d.ts +31 -10
  176. package/dist/core/Step.d.ts.map +1 -0
  177. package/dist/{src/core → core}/Step.js +104 -9
  178. package/dist/core/Step.js.map +1 -0
  179. package/dist/core/ToolManager.d.ts.map +1 -0
  180. package/dist/core/ToolManager.js.map +1 -0
  181. package/dist/{cjs/src/index.d.ts → index.d.ts} +4 -1
  182. package/dist/index.d.ts.map +1 -0
  183. package/dist/{src/index.js → index.js} +3 -0
  184. package/dist/index.js.map +1 -0
  185. package/dist/providers/AnthropicProvider.d.ts.map +1 -0
  186. package/dist/{src/providers → providers}/AnthropicProvider.js +17 -17
  187. package/dist/providers/AnthropicProvider.js.map +1 -0
  188. package/dist/providers/GeminiProvider.d.ts.map +1 -0
  189. package/dist/{src/providers → providers}/GeminiProvider.js +123 -51
  190. package/dist/providers/GeminiProvider.js.map +1 -0
  191. package/dist/providers/OpenAIProvider.d.ts.map +1 -0
  192. package/dist/{src/providers → providers}/OpenAIProvider.js +18 -18
  193. package/dist/providers/OpenAIProvider.js.map +1 -0
  194. package/dist/providers/OpenRouterProvider.d.ts.map +1 -0
  195. package/dist/{src/providers → providers}/OpenRouterProvider.js +18 -18
  196. package/dist/providers/OpenRouterProvider.js.map +1 -0
  197. package/dist/providers/index.d.ts.map +1 -0
  198. package/dist/providers/index.js.map +1 -0
  199. package/dist/{src/types → types}/agent.d.ts +15 -3
  200. package/dist/types/agent.d.ts.map +1 -0
  201. package/dist/types/agent.js.map +1 -0
  202. package/dist/types/ai.d.ts.map +1 -0
  203. package/dist/types/ai.js.map +1 -0
  204. package/dist/types/history.d.ts.map +1 -0
  205. package/dist/types/history.js.map +1 -0
  206. package/dist/{src/types → types}/index.d.ts +2 -1
  207. package/dist/types/index.d.ts.map +1 -0
  208. package/dist/{src/types → types}/index.js +1 -0
  209. package/dist/types/index.js.map +1 -0
  210. package/dist/types/persistence.d.ts.map +1 -0
  211. package/dist/types/persistence.js.map +1 -0
  212. package/dist/{src/types → types}/route.d.ts +111 -12
  213. package/dist/types/route.d.ts.map +1 -0
  214. package/dist/{src/types → types}/route.js.map +1 -1
  215. package/dist/types/routing.d.ts.map +1 -0
  216. package/dist/{cjs/src/types → types}/routing.js.map +1 -1
  217. package/dist/types/schema.d.ts.map +1 -0
  218. package/dist/{cjs/src/types → types}/schema.js.map +1 -1
  219. package/dist/types/session.d.ts.map +1 -0
  220. package/dist/{src/types → types}/session.js.map +1 -1
  221. package/dist/types/template.d.ts +88 -0
  222. package/dist/types/template.d.ts.map +1 -0
  223. package/dist/{cjs/src/types → types}/template.js.map +1 -1
  224. package/dist/types/tool.d.ts.map +1 -0
  225. package/dist/types/tool.js.map +1 -0
  226. package/dist/utils/clone.d.ts.map +1 -0
  227. package/dist/utils/clone.js.map +1 -0
  228. package/dist/utils/condition.d.ts +38 -0
  229. package/dist/utils/condition.d.ts.map +1 -0
  230. package/dist/utils/condition.js +161 -0
  231. package/dist/utils/condition.js.map +1 -0
  232. package/dist/utils/event.d.ts.map +1 -0
  233. package/dist/utils/event.js.map +1 -0
  234. package/dist/utils/history.d.ts.map +1 -0
  235. package/dist/utils/history.js.map +1 -0
  236. package/dist/utils/id.d.ts.map +1 -0
  237. package/dist/utils/id.js.map +1 -0
  238. package/dist/{src/utils → utils}/index.d.ts +3 -1
  239. package/dist/utils/index.d.ts.map +1 -0
  240. package/dist/{src/utils → utils}/index.js +5 -1
  241. package/dist/utils/index.js.map +1 -0
  242. package/dist/utils/json.d.ts +16 -0
  243. package/dist/utils/json.d.ts.map +1 -0
  244. package/dist/utils/json.js +43 -0
  245. package/dist/utils/json.js.map +1 -0
  246. package/dist/utils/logger.d.ts.map +1 -0
  247. package/dist/utils/logger.js.map +1 -0
  248. package/dist/{cjs/src/utils → utils}/retry.d.ts +0 -3
  249. package/dist/utils/retry.d.ts.map +1 -0
  250. package/dist/{src/utils → utils}/retry.js +5 -4
  251. package/dist/utils/retry.js.map +1 -0
  252. package/dist/utils/session.d.ts.map +1 -0
  253. package/dist/utils/session.js.map +1 -0
  254. package/dist/{cjs/src/utils → utils}/template.d.ts +48 -0
  255. package/dist/utils/template.d.ts.map +1 -0
  256. package/dist/{src/utils → utils}/template.js +98 -0
  257. package/dist/utils/template.js.map +1 -0
  258. package/docs/README.md +1 -0
  259. package/docs/api/README.md +237 -12
  260. package/docs/api/overview.md +206 -3
  261. package/docs/architecture/data-extraction-flow.md +363 -0
  262. package/docs/architecture/multi-step-execution.md +243 -0
  263. package/docs/core/agent/README.md +156 -5
  264. package/docs/core/agent/rules-and-prohibitions.md +113 -0
  265. package/docs/core/agent/session-management.md +1 -1
  266. package/docs/core/ai-integration/prompt-composition.md +135 -0
  267. package/docs/core/ai-integration/response-processing.md +146 -0
  268. package/docs/core/conversation-flows/data-collection.md +143 -0
  269. package/docs/core/conversation-flows/routes.md +2 -2
  270. package/docs/core/conversation-flows/step-transitions.md +132 -0
  271. package/docs/core/conversation-flows/steps.md +112 -0
  272. package/docs/core/error-handling.md +193 -0
  273. package/docs/core/routing/intelligent-routing.md +118 -0
  274. package/docs/guides/getting-started/README.md +284 -3
  275. package/docs/guides/migration/README.md +27 -0
  276. package/docs/guides/migration/flexible-routing-conditions.md +375 -0
  277. package/docs/guides/migration/multi-step-execution.md +373 -0
  278. package/examples/advanced-patterns/knowledge-based-agent.ts +101 -24
  279. package/examples/advanced-patterns/persistent-onboarding.ts +40 -5
  280. package/examples/advanced-patterns/route-lifecycle-hooks.ts +82 -12
  281. package/examples/advanced-patterns/streaming-responses.ts +2 -2
  282. package/examples/ai-providers/anthropic-integration.ts +4 -4
  283. package/examples/ai-providers/openai-integration.ts +1 -1
  284. package/examples/condition-patterns/function-only-conditions.ts +365 -0
  285. package/examples/condition-patterns/mixed-array-conditions.ts +477 -0
  286. package/examples/condition-patterns/route-skipif-patterns.ts +468 -0
  287. package/examples/condition-patterns/step-skipif-patterns.ts +0 -0
  288. package/examples/condition-patterns/string-only-conditions.ts +296 -0
  289. package/examples/conversation-flows/completion-transitions.ts +48 -7
  290. package/examples/core-concepts/basic-agent.ts +54 -33
  291. package/examples/core-concepts/schema-driven-extraction.ts +33 -9
  292. package/examples/core-concepts/session-management.ts +51 -16
  293. package/examples/integrations/database-integration.ts +6 -6
  294. package/examples/integrations/healthcare-integration.ts +10 -10
  295. package/examples/integrations/search-integration.ts +8 -8
  296. package/examples/integrations/server-session-management.ts +8 -8
  297. package/examples/persistence/database-persistence.ts +15 -15
  298. package/examples/persistence/memory-sessions.ts +3 -3
  299. package/examples/persistence/redis-persistence.ts +7 -9
  300. package/examples/tools/data-enrichment-tools.ts +4 -4
  301. package/package.json +6 -4
  302. package/src/adapters/PrismaAdapter.ts +3 -2
  303. package/src/adapters/RedisAdapter.ts +3 -3
  304. package/src/core/Agent.ts +78 -2
  305. package/src/core/BatchExecutor.ts +1166 -0
  306. package/src/core/BatchPromptBuilder.ts +293 -0
  307. package/src/core/PromptComposer.ts +53 -16
  308. package/src/core/ResponseEngine.ts +168 -29
  309. package/src/core/ResponseModal.ts +954 -74
  310. package/src/core/ResponsePipeline.ts +17 -9
  311. package/src/core/Route.ts +223 -22
  312. package/src/core/RoutingEngine.ts +426 -83
  313. package/src/core/Step.ts +144 -16
  314. package/src/index.ts +19 -0
  315. package/src/providers/AnthropicProvider.ts +17 -17
  316. package/src/providers/GeminiProvider.ts +129 -60
  317. package/src/providers/OpenAIProvider.ts +18 -18
  318. package/src/providers/OpenRouterProvider.ts +18 -18
  319. package/src/types/agent.ts +15 -3
  320. package/src/types/index.ts +12 -1
  321. package/src/types/route.ts +131 -12
  322. package/src/types/template.ts +70 -2
  323. package/src/utils/condition.ts +190 -0
  324. package/src/utils/index.ts +12 -0
  325. package/src/utils/json.ts +46 -0
  326. package/src/utils/retry.ts +5 -4
  327. package/src/utils/template.ts +109 -0
  328. package/dist/cjs/src/adapters/MemoryAdapter.d.ts.map +0 -1
  329. package/dist/cjs/src/adapters/MemoryAdapter.js.map +0 -1
  330. package/dist/cjs/src/adapters/MongoAdapter.d.ts.map +0 -1
  331. package/dist/cjs/src/adapters/MongoAdapter.js.map +0 -1
  332. package/dist/cjs/src/adapters/OpenSearchAdapter.d.ts.map +0 -1
  333. package/dist/cjs/src/adapters/OpenSearchAdapter.js.map +0 -1
  334. package/dist/cjs/src/adapters/PostgreSQLAdapter.d.ts.map +0 -1
  335. package/dist/cjs/src/adapters/PostgreSQLAdapter.js.map +0 -1
  336. package/dist/cjs/src/adapters/PrismaAdapter.d.ts.map +0 -1
  337. package/dist/cjs/src/adapters/PrismaAdapter.js.map +0 -1
  338. package/dist/cjs/src/adapters/RedisAdapter.d.ts.map +0 -1
  339. package/dist/cjs/src/adapters/RedisAdapter.js.map +0 -1
  340. package/dist/cjs/src/adapters/SQLiteAdapter.d.ts.map +0 -1
  341. package/dist/cjs/src/adapters/SQLiteAdapter.js.map +0 -1
  342. package/dist/cjs/src/adapters/index.d.ts.map +0 -1
  343. package/dist/cjs/src/adapters/index.js.map +0 -1
  344. package/dist/cjs/src/constants/index.d.ts.map +0 -1
  345. package/dist/cjs/src/constants/index.js.map +0 -1
  346. package/dist/cjs/src/core/Agent.d.ts.map +0 -1
  347. package/dist/cjs/src/core/Agent.js.map +0 -1
  348. package/dist/cjs/src/core/Events.d.ts.map +0 -1
  349. package/dist/cjs/src/core/Events.js.map +0 -1
  350. package/dist/cjs/src/core/PersistenceManager.d.ts.map +0 -1
  351. package/dist/cjs/src/core/PersistenceManager.js.map +0 -1
  352. package/dist/cjs/src/core/PromptComposer.d.ts.map +0 -1
  353. package/dist/cjs/src/core/PromptComposer.js.map +0 -1
  354. package/dist/cjs/src/core/ResponseEngine.d.ts.map +0 -1
  355. package/dist/cjs/src/core/ResponseEngine.js +0 -84
  356. package/dist/cjs/src/core/ResponseEngine.js.map +0 -1
  357. package/dist/cjs/src/core/ResponseModal.d.ts.map +0 -1
  358. package/dist/cjs/src/core/ResponseModal.js.map +0 -1
  359. package/dist/cjs/src/core/ResponsePipeline.d.ts.map +0 -1
  360. package/dist/cjs/src/core/ResponsePipeline.js.map +0 -1
  361. package/dist/cjs/src/core/Route.d.ts.map +0 -1
  362. package/dist/cjs/src/core/Route.js.map +0 -1
  363. package/dist/cjs/src/core/RoutingEngine.d.ts.map +0 -1
  364. package/dist/cjs/src/core/RoutingEngine.js.map +0 -1
  365. package/dist/cjs/src/core/SessionManager.d.ts.map +0 -1
  366. package/dist/cjs/src/core/SessionManager.js.map +0 -1
  367. package/dist/cjs/src/core/Step.d.ts.map +0 -1
  368. package/dist/cjs/src/core/Step.js.map +0 -1
  369. package/dist/cjs/src/core/ToolManager.d.ts.map +0 -1
  370. package/dist/cjs/src/core/ToolManager.js.map +0 -1
  371. package/dist/cjs/src/index.d.ts.map +0 -1
  372. package/dist/cjs/src/index.js.map +0 -1
  373. package/dist/cjs/src/providers/AnthropicProvider.d.ts.map +0 -1
  374. package/dist/cjs/src/providers/AnthropicProvider.js.map +0 -1
  375. package/dist/cjs/src/providers/GeminiProvider.d.ts.map +0 -1
  376. package/dist/cjs/src/providers/GeminiProvider.js.map +0 -1
  377. package/dist/cjs/src/providers/OpenAIProvider.d.ts.map +0 -1
  378. package/dist/cjs/src/providers/OpenAIProvider.js.map +0 -1
  379. package/dist/cjs/src/providers/OpenRouterProvider.d.ts.map +0 -1
  380. package/dist/cjs/src/providers/OpenRouterProvider.js.map +0 -1
  381. package/dist/cjs/src/providers/index.d.ts.map +0 -1
  382. package/dist/cjs/src/providers/index.js.map +0 -1
  383. package/dist/cjs/src/types/agent.d.ts.map +0 -1
  384. package/dist/cjs/src/types/agent.js.map +0 -1
  385. package/dist/cjs/src/types/ai.d.ts.map +0 -1
  386. package/dist/cjs/src/types/ai.js.map +0 -1
  387. package/dist/cjs/src/types/history.d.ts.map +0 -1
  388. package/dist/cjs/src/types/history.js.map +0 -1
  389. package/dist/cjs/src/types/index.d.ts.map +0 -1
  390. package/dist/cjs/src/types/index.js.map +0 -1
  391. package/dist/cjs/src/types/persistence.d.ts.map +0 -1
  392. package/dist/cjs/src/types/persistence.js.map +0 -1
  393. package/dist/cjs/src/types/route.d.ts.map +0 -1
  394. package/dist/cjs/src/types/routing.d.ts.map +0 -1
  395. package/dist/cjs/src/types/schema.d.ts.map +0 -1
  396. package/dist/cjs/src/types/session.d.ts.map +0 -1
  397. package/dist/cjs/src/types/session.js.map +0 -1
  398. package/dist/cjs/src/types/template.d.ts +0 -30
  399. package/dist/cjs/src/types/template.d.ts.map +0 -1
  400. package/dist/cjs/src/types/tool.d.ts.map +0 -1
  401. package/dist/cjs/src/types/tool.js.map +0 -1
  402. package/dist/cjs/src/utils/clone.d.ts.map +0 -1
  403. package/dist/cjs/src/utils/clone.js.map +0 -1
  404. package/dist/cjs/src/utils/event.d.ts.map +0 -1
  405. package/dist/cjs/src/utils/event.js.map +0 -1
  406. package/dist/cjs/src/utils/history.d.ts.map +0 -1
  407. package/dist/cjs/src/utils/history.js.map +0 -1
  408. package/dist/cjs/src/utils/id.d.ts.map +0 -1
  409. package/dist/cjs/src/utils/id.js.map +0 -1
  410. package/dist/cjs/src/utils/index.d.ts.map +0 -1
  411. package/dist/cjs/src/utils/index.js.map +0 -1
  412. package/dist/cjs/src/utils/logger.d.ts.map +0 -1
  413. package/dist/cjs/src/utils/logger.js.map +0 -1
  414. package/dist/cjs/src/utils/retry.d.ts.map +0 -1
  415. package/dist/cjs/src/utils/retry.js.map +0 -1
  416. package/dist/cjs/src/utils/session.d.ts.map +0 -1
  417. package/dist/cjs/src/utils/session.js.map +0 -1
  418. package/dist/cjs/src/utils/template.d.ts.map +0 -1
  419. package/dist/cjs/src/utils/template.js.map +0 -1
  420. package/dist/src/adapters/MemoryAdapter.js.map +0 -1
  421. package/dist/src/adapters/MongoAdapter.js.map +0 -1
  422. package/dist/src/adapters/OpenSearchAdapter.js.map +0 -1
  423. package/dist/src/adapters/PostgreSQLAdapter.js.map +0 -1
  424. package/dist/src/adapters/PrismaAdapter.js.map +0 -1
  425. package/dist/src/adapters/RedisAdapter.js.map +0 -1
  426. package/dist/src/adapters/SQLiteAdapter.js.map +0 -1
  427. package/dist/src/adapters/index.js.map +0 -1
  428. package/dist/src/constants/index.js.map +0 -1
  429. package/dist/src/core/Agent.d.ts.map +0 -1
  430. package/dist/src/core/Agent.js.map +0 -1
  431. package/dist/src/core/Events.js.map +0 -1
  432. package/dist/src/core/PersistenceManager.js.map +0 -1
  433. package/dist/src/core/PromptComposer.d.ts.map +0 -1
  434. package/dist/src/core/PromptComposer.js.map +0 -1
  435. package/dist/src/core/ResponseEngine.js +0 -80
  436. package/dist/src/core/ResponseEngine.js.map +0 -1
  437. package/dist/src/core/ResponseModal.d.ts.map +0 -1
  438. package/dist/src/core/ResponseModal.js.map +0 -1
  439. package/dist/src/core/ResponsePipeline.d.ts.map +0 -1
  440. package/dist/src/core/ResponsePipeline.js.map +0 -1
  441. package/dist/src/core/Route.d.ts.map +0 -1
  442. package/dist/src/core/Route.js.map +0 -1
  443. package/dist/src/core/RoutingEngine.d.ts.map +0 -1
  444. package/dist/src/core/RoutingEngine.js.map +0 -1
  445. package/dist/src/core/SessionManager.js.map +0 -1
  446. package/dist/src/core/Step.d.ts.map +0 -1
  447. package/dist/src/core/Step.js.map +0 -1
  448. package/dist/src/core/ToolManager.js.map +0 -1
  449. package/dist/src/index.d.ts.map +0 -1
  450. package/dist/src/index.js.map +0 -1
  451. package/dist/src/providers/AnthropicProvider.js.map +0 -1
  452. package/dist/src/providers/GeminiProvider.js.map +0 -1
  453. package/dist/src/providers/OpenAIProvider.js.map +0 -1
  454. package/dist/src/providers/OpenRouterProvider.js.map +0 -1
  455. package/dist/src/providers/index.js.map +0 -1
  456. package/dist/src/types/agent.d.ts.map +0 -1
  457. package/dist/src/types/agent.js.map +0 -1
  458. package/dist/src/types/history.js.map +0 -1
  459. package/dist/src/types/index.js.map +0 -1
  460. package/dist/src/types/persistence.js.map +0 -1
  461. package/dist/src/types/route.d.ts.map +0 -1
  462. package/dist/src/types/template.d.ts +0 -30
  463. package/dist/src/types/template.d.ts.map +0 -1
  464. package/dist/src/types/tool.js.map +0 -1
  465. package/dist/src/utils/clone.js.map +0 -1
  466. package/dist/src/utils/event.js.map +0 -1
  467. package/dist/src/utils/history.js.map +0 -1
  468. package/dist/src/utils/id.js.map +0 -1
  469. package/dist/src/utils/index.d.ts.map +0 -1
  470. package/dist/src/utils/index.js.map +0 -1
  471. package/dist/src/utils/logger.js.map +0 -1
  472. package/dist/src/utils/retry.d.ts.map +0 -1
  473. package/dist/src/utils/retry.js.map +0 -1
  474. package/dist/src/utils/session.js.map +0 -1
  475. package/dist/src/utils/template.d.ts.map +0 -1
  476. package/dist/src/utils/template.js.map +0 -1
  477. /package/dist/{cjs/src/adapters → adapters}/MemoryAdapter.d.ts +0 -0
  478. /package/dist/{src/adapters → adapters}/MemoryAdapter.js +0 -0
  479. /package/dist/{cjs/src/adapters → adapters}/MongoAdapter.d.ts +0 -0
  480. /package/dist/{src/adapters → adapters}/MongoAdapter.js +0 -0
  481. /package/dist/{cjs/src/adapters → adapters}/OpenSearchAdapter.d.ts +0 -0
  482. /package/dist/{src/adapters → adapters}/OpenSearchAdapter.js +0 -0
  483. /package/dist/{cjs/src/adapters → adapters}/PostgreSQLAdapter.d.ts +0 -0
  484. /package/dist/{src/adapters → adapters}/PostgreSQLAdapter.js +0 -0
  485. /package/dist/{cjs/src/adapters → adapters}/PrismaAdapter.d.ts +0 -0
  486. /package/dist/{cjs/src/adapters → adapters}/RedisAdapter.d.ts +0 -0
  487. /package/dist/{cjs/src/adapters → adapters}/SQLiteAdapter.d.ts +0 -0
  488. /package/dist/{src/adapters → adapters}/SQLiteAdapter.js +0 -0
  489. /package/dist/{cjs/src/adapters → adapters}/index.d.ts +0 -0
  490. /package/dist/{src/adapters → adapters}/index.js +0 -0
  491. /package/dist/{src → cjs}/adapters/MemoryAdapter.d.ts +0 -0
  492. /package/dist/{src → cjs}/adapters/MemoryAdapter.d.ts.map +0 -0
  493. /package/dist/cjs/{src/adapters → adapters}/MemoryAdapter.js +0 -0
  494. /package/dist/{src → cjs}/adapters/MongoAdapter.d.ts +0 -0
  495. /package/dist/{src → cjs}/adapters/MongoAdapter.d.ts.map +0 -0
  496. /package/dist/cjs/{src/adapters → adapters}/MongoAdapter.js +0 -0
  497. /package/dist/{src → cjs}/adapters/OpenSearchAdapter.d.ts +0 -0
  498. /package/dist/{src → cjs}/adapters/OpenSearchAdapter.d.ts.map +0 -0
  499. /package/dist/cjs/{src/adapters → adapters}/OpenSearchAdapter.js +0 -0
  500. /package/dist/{src → cjs}/adapters/PostgreSQLAdapter.d.ts +0 -0
  501. /package/dist/{src → cjs}/adapters/PostgreSQLAdapter.d.ts.map +0 -0
  502. /package/dist/cjs/{src/adapters → adapters}/PostgreSQLAdapter.js +0 -0
  503. /package/dist/{src → cjs}/adapters/PrismaAdapter.d.ts +0 -0
  504. /package/dist/{src → cjs}/adapters/RedisAdapter.d.ts +0 -0
  505. /package/dist/{src → cjs}/adapters/RedisAdapter.d.ts.map +0 -0
  506. /package/dist/{src → cjs}/adapters/SQLiteAdapter.d.ts +0 -0
  507. /package/dist/{src → cjs}/adapters/SQLiteAdapter.d.ts.map +0 -0
  508. /package/dist/cjs/{src/adapters → adapters}/SQLiteAdapter.js +0 -0
  509. /package/dist/{src → cjs}/adapters/index.d.ts +0 -0
  510. /package/dist/{src → cjs}/adapters/index.d.ts.map +0 -0
  511. /package/dist/cjs/{src/adapters → adapters}/index.js +0 -0
  512. /package/dist/cjs/{src/constants → constants}/index.d.ts +0 -0
  513. /package/dist/{src → cjs}/constants/index.d.ts.map +0 -0
  514. /package/dist/cjs/{src/constants → constants}/index.js +0 -0
  515. /package/dist/cjs/{src/core → core}/Events.d.ts +0 -0
  516. /package/dist/{src → cjs}/core/Events.d.ts.map +0 -0
  517. /package/dist/cjs/{src/core → core}/Events.js +0 -0
  518. /package/dist/cjs/{src/core → core}/PersistenceManager.d.ts +0 -0
  519. /package/dist/{src → cjs}/core/PersistenceManager.d.ts.map +0 -0
  520. /package/dist/cjs/{src/core → core}/PersistenceManager.js +0 -0
  521. /package/dist/cjs/{src/core → core}/ResponseEngine.d.ts +0 -0
  522. /package/dist/cjs/{src/core → core}/SessionManager.d.ts +0 -0
  523. /package/dist/{src → cjs}/core/SessionManager.d.ts.map +0 -0
  524. /package/dist/cjs/{src/core → core}/SessionManager.js +0 -0
  525. /package/dist/cjs/{src/core → core}/ToolManager.d.ts +0 -0
  526. /package/dist/{src → cjs}/core/ToolManager.d.ts.map +0 -0
  527. /package/dist/cjs/{src/core → core}/ToolManager.js +0 -0
  528. /package/dist/cjs/{src/providers → providers}/AnthropicProvider.d.ts +0 -0
  529. /package/dist/{src → cjs}/providers/AnthropicProvider.d.ts.map +0 -0
  530. /package/dist/cjs/{src/providers → providers}/GeminiProvider.d.ts +0 -0
  531. /package/dist/cjs/{src/providers → providers}/OpenAIProvider.d.ts +0 -0
  532. /package/dist/{src → cjs}/providers/OpenAIProvider.d.ts.map +0 -0
  533. /package/dist/cjs/{src/providers → providers}/OpenRouterProvider.d.ts +0 -0
  534. /package/dist/{src → cjs}/providers/OpenRouterProvider.d.ts.map +0 -0
  535. /package/dist/cjs/{src/providers → providers}/index.d.ts +0 -0
  536. /package/dist/{src → cjs}/providers/index.d.ts.map +0 -0
  537. /package/dist/cjs/{src/providers → providers}/index.js +0 -0
  538. /package/dist/cjs/{src/types → types}/agent.js +0 -0
  539. /package/dist/cjs/{src/types → types}/ai.d.ts +0 -0
  540. /package/dist/{src → cjs}/types/ai.d.ts.map +0 -0
  541. /package/dist/cjs/{src/types → types}/ai.js +0 -0
  542. /package/dist/cjs/{src/types → types}/history.d.ts +0 -0
  543. /package/dist/{src → cjs}/types/history.d.ts.map +0 -0
  544. /package/dist/cjs/{src/types → types}/history.js +0 -0
  545. /package/dist/cjs/{src/types → types}/persistence.d.ts +0 -0
  546. /package/dist/{src → cjs}/types/persistence.d.ts.map +0 -0
  547. /package/dist/cjs/{src/types → types}/persistence.js +0 -0
  548. /package/dist/cjs/{src/types → types}/route.js +0 -0
  549. /package/dist/cjs/{src/types → types}/routing.d.ts +0 -0
  550. /package/dist/{src → cjs}/types/routing.d.ts.map +0 -0
  551. /package/dist/cjs/{src/types → types}/routing.js +0 -0
  552. /package/dist/{src → cjs}/types/routing.js.map +0 -0
  553. /package/dist/cjs/{src/types → types}/schema.d.ts +0 -0
  554. /package/dist/{src → cjs}/types/schema.d.ts.map +0 -0
  555. /package/dist/cjs/{src/types → types}/schema.js +0 -0
  556. /package/dist/{src → cjs}/types/schema.js.map +0 -0
  557. /package/dist/cjs/{src/types → types}/session.d.ts +0 -0
  558. /package/dist/{src → cjs}/types/session.d.ts.map +0 -0
  559. /package/dist/cjs/{src/types → types}/session.js +0 -0
  560. /package/dist/cjs/{src/types → types}/template.js +0 -0
  561. /package/dist/{src → cjs}/types/template.js.map +0 -0
  562. /package/dist/cjs/{src/types → types}/tool.d.ts +0 -0
  563. /package/dist/{src → cjs}/types/tool.d.ts.map +0 -0
  564. /package/dist/cjs/{src/types → types}/tool.js +0 -0
  565. /package/dist/cjs/{src/utils → utils}/clone.d.ts +0 -0
  566. /package/dist/{src → cjs}/utils/clone.d.ts.map +0 -0
  567. /package/dist/cjs/{src/utils → utils}/clone.js +0 -0
  568. /package/dist/cjs/{src/utils → utils}/event.d.ts +0 -0
  569. /package/dist/{src → cjs}/utils/event.d.ts.map +0 -0
  570. /package/dist/cjs/{src/utils → utils}/event.js +0 -0
  571. /package/dist/cjs/{src/utils → utils}/history.d.ts +0 -0
  572. /package/dist/{src → cjs}/utils/history.d.ts.map +0 -0
  573. /package/dist/cjs/{src/utils → utils}/history.js +0 -0
  574. /package/dist/cjs/{src/utils → utils}/id.d.ts +0 -0
  575. /package/dist/{src → cjs}/utils/id.d.ts.map +0 -0
  576. /package/dist/cjs/{src/utils → utils}/id.js +0 -0
  577. /package/dist/cjs/{src/utils → utils}/logger.d.ts +0 -0
  578. /package/dist/{src → cjs}/utils/logger.d.ts.map +0 -0
  579. /package/dist/cjs/{src/utils → utils}/logger.js +0 -0
  580. /package/dist/cjs/{src/utils → utils}/session.d.ts +0 -0
  581. /package/dist/{src → cjs}/utils/session.d.ts.map +0 -0
  582. /package/dist/cjs/{src/utils → utils}/session.js +0 -0
  583. /package/dist/{src/constants → constants}/index.d.ts +0 -0
  584. /package/dist/{src/constants → constants}/index.js +0 -0
  585. /package/dist/{src/core → core}/Events.d.ts +0 -0
  586. /package/dist/{src/core → core}/Events.js +0 -0
  587. /package/dist/{src/core → core}/PersistenceManager.d.ts +0 -0
  588. /package/dist/{src/core → core}/PersistenceManager.js +0 -0
  589. /package/dist/{src/core → core}/ResponseEngine.d.ts +0 -0
  590. /package/dist/{src/core → core}/SessionManager.d.ts +0 -0
  591. /package/dist/{src/core → core}/SessionManager.js +0 -0
  592. /package/dist/{src/core → core}/ToolManager.d.ts +0 -0
  593. /package/dist/{src/core → core}/ToolManager.js +0 -0
  594. /package/dist/{src/providers → providers}/AnthropicProvider.d.ts +0 -0
  595. /package/dist/{src/providers → providers}/GeminiProvider.d.ts +0 -0
  596. /package/dist/{src/providers → providers}/OpenAIProvider.d.ts +0 -0
  597. /package/dist/{src/providers → providers}/OpenRouterProvider.d.ts +0 -0
  598. /package/dist/{src/providers → providers}/index.d.ts +0 -0
  599. /package/dist/{src/providers → providers}/index.js +0 -0
  600. /package/dist/{src/types → types}/agent.js +0 -0
  601. /package/dist/{src/types → types}/ai.d.ts +0 -0
  602. /package/dist/{src/types → types}/ai.js +0 -0
  603. /package/dist/{src/types → types}/history.d.ts +0 -0
  604. /package/dist/{src/types → types}/history.js +0 -0
  605. /package/dist/{src/types → types}/persistence.d.ts +0 -0
  606. /package/dist/{src/types → types}/persistence.js +0 -0
  607. /package/dist/{src/types → types}/route.js +0 -0
  608. /package/dist/{src/types → types}/routing.d.ts +0 -0
  609. /package/dist/{src/types → types}/routing.js +0 -0
  610. /package/dist/{src/types → types}/schema.d.ts +0 -0
  611. /package/dist/{src/types → types}/schema.js +0 -0
  612. /package/dist/{src/types → types}/session.d.ts +0 -0
  613. /package/dist/{src/types → types}/session.js +0 -0
  614. /package/dist/{src/types → types}/template.js +0 -0
  615. /package/dist/{src/types → types}/tool.d.ts +0 -0
  616. /package/dist/{src/types → types}/tool.js +0 -0
  617. /package/dist/{src/utils → utils}/clone.d.ts +0 -0
  618. /package/dist/{src/utils → utils}/clone.js +0 -0
  619. /package/dist/{src/utils → utils}/event.d.ts +0 -0
  620. /package/dist/{src/utils → utils}/event.js +0 -0
  621. /package/dist/{src/utils → utils}/history.d.ts +0 -0
  622. /package/dist/{src/utils → utils}/history.js +0 -0
  623. /package/dist/{src/utils → utils}/id.d.ts +0 -0
  624. /package/dist/{src/utils → utils}/id.js +0 -0
  625. /package/dist/{src/utils → utils}/logger.d.ts +0 -0
  626. /package/dist/{src/utils → utils}/logger.js +0 -0
  627. /package/dist/{src/utils → utils}/session.d.ts +0 -0
  628. /package/dist/{src/utils → utils}/session.js +0 -0
@@ -1,9 +1,7 @@
1
1
  import { enterRoute, mergeCollected } from "../utils";
2
2
  import { PromptComposer } from "./PromptComposer";
3
- import { getLastMessageFromHistory } from "../utils/event";
4
- import { logger } from "../utils/logger";
5
- import { render } from "../utils/template";
6
3
  import { END_ROUTE_ID } from "../constants";
4
+ import { createTemplateContext, getLastMessageFromHistory, logger } from "../utils";
7
5
  export class RoutingEngine {
8
6
  constructor(options) {
9
7
  this.options = options;
@@ -36,21 +34,26 @@ export class RoutingEngine {
36
34
  const updatedSession = this.enterRouteIfNeeded(session, route);
37
35
  // Check if this single route is complete (use updated session data)
38
36
  const completedRoutes = route.isComplete(updatedSession.data || {}) ? [route] : [];
39
- // Get candidate steps
37
+ // Get candidate steps using new condition evaluation
38
+ const templateContext = createTemplateContext({
39
+ context,
40
+ session: updatedSession,
41
+ history,
42
+ data: updatedSession.data
43
+ });
40
44
  const currentStep = updatedSession.currentStep
41
45
  ? route.getStep(updatedSession.currentStep.id)
42
46
  : undefined;
43
- const candidates = this.getCandidateSteps(route, currentStep, updatedSession.data || {});
47
+ const candidates = await this.getCandidateStepsWithConditions(route, currentStep, templateContext);
44
48
  if (candidates.length === 0) {
45
49
  logger.warn(`[RoutingEngine] Single-route: No valid steps found`);
46
50
  return { selectedRoute, session: updatedSession };
47
51
  }
48
- // If only one candidate, no need for AI selection
52
+ // If only one candidate, check if it's a completion marker
49
53
  if (candidates.length === 1) {
50
54
  const candidate = candidates[0];
51
- const isRouteComplete = candidate.isRouteComplete;
52
- if (isRouteComplete) {
53
- logger.debug(`[RoutingEngine] Single-route: Route complete - all data collected, END_ROUTE reached`);
55
+ if (candidate.isRouteComplete) {
56
+ logger.debug(`[RoutingEngine] Single-route: Route complete - all required fields collected or END_ROUTE reached`);
54
57
  // Don't return a selectedStep when route is complete - there's no step to enter
55
58
  return {
56
59
  selectedRoute,
@@ -73,17 +76,27 @@ export class RoutingEngine {
73
76
  }
74
77
  // No candidates means route is likely complete or has no valid next steps
75
78
  if (candidates.length === 0) {
76
- logger.debug(`[RoutingEngine] Single-route: No valid steps found, route may be complete`);
79
+ const dataComplete = route.isComplete(updatedSession.data || {});
80
+ logger.debug(`[RoutingEngine] Single-route: No valid steps found - ` +
81
+ `(data: ${dataComplete ? 'complete' : 'incomplete'}, marking as ${dataComplete ? 'complete' : 'incomplete'})`);
77
82
  return {
78
83
  selectedRoute,
79
84
  selectedStep: undefined,
80
85
  session: updatedSession,
81
- isRouteComplete: true, // Assume complete if no valid steps
86
+ isRouteComplete: dataComplete,
82
87
  completedRoutes,
83
88
  };
84
89
  }
85
90
  // Multiple candidates - use AI to select best step
86
91
  const lastUserMessage = getLastMessageFromHistory(history);
92
+ // Collect AI context strings from step conditions
93
+ const stepConditionContext = [];
94
+ for (const candidate of candidates) {
95
+ const whenResult = await candidate.step.evaluateWhen(templateContext);
96
+ stepConditionContext.push(...whenResult.aiContextStrings);
97
+ }
98
+ // Check if any candidate is a completion marker (isRouteComplete = true)
99
+ const hasCompletionOption = candidates.some(c => c.isRouteComplete);
87
100
  const stepPrompt = await this.buildStepSelectionPrompt({
88
101
  route,
89
102
  currentStep,
@@ -94,8 +107,10 @@ export class RoutingEngine {
94
107
  agentOptions,
95
108
  context,
96
109
  session: updatedSession,
110
+ stepConditionContext,
111
+ includeEndRoute: hasCompletionOption,
97
112
  });
98
- const stepSchema = this.buildStepSelectionSchema(candidates.map((c) => c.step));
113
+ const stepSchema = this.buildStepSelectionSchema(candidates.filter(c => !c.isRouteComplete).map((c) => c.step), hasCompletionOption);
99
114
  const stepResult = await provider.generateMessage({
100
115
  prompt: stepPrompt,
101
116
  history,
@@ -107,6 +122,19 @@ export class RoutingEngine {
107
122
  },
108
123
  });
109
124
  const selectedStepId = stepResult.structured?.selectedStepId;
125
+ // Check if AI selected END_ROUTE
126
+ if (selectedStepId === END_ROUTE_ID) {
127
+ logger.debug(`[RoutingEngine] Single-route: AI selected END_ROUTE - completing route`);
128
+ logger.debug(`[RoutingEngine] Single-route: Reasoning: ${stepResult.structured?.reasoning}`);
129
+ return {
130
+ selectedRoute,
131
+ selectedStep: undefined,
132
+ responseDirectives: stepResult.structured?.responseDirectives,
133
+ session: updatedSession,
134
+ isRouteComplete: true,
135
+ completedRoutes,
136
+ };
137
+ }
110
138
  const selectedStep = candidates.find((c) => c.step.id === selectedStepId);
111
139
  if (selectedStep) {
112
140
  logger.debug(`[RoutingEngine] Single-route: AI selected step: ${selectedStep.step.id}`);
@@ -124,16 +152,17 @@ export class RoutingEngine {
124
152
  };
125
153
  }
126
154
  /**
127
- * Recursively traverse step chain to find first non-skipped step or END_ROUTE
155
+ * Recursively traverse step chain to find first non-skipped step or END_ROUTE using new condition evaluation
128
156
  * @private
129
157
  */
130
- findFirstValidStepRecursive(currentStep, data, visited) {
158
+ async findFirstValidStepRecursiveWithConditions(currentStep, templateContext, visited) {
131
159
  // Prevent infinite loops
132
160
  if (visited.has(currentStep.id)) {
133
- return {};
161
+ return { aiContextStrings: [] };
134
162
  }
135
163
  visited.add(currentStep.id);
136
164
  const transitions = currentStep.getTransitions();
165
+ const allAiContextStrings = [];
137
166
  for (const transition of transitions) {
138
167
  const target = transition;
139
168
  // Check for END_ROUTE transition
@@ -141,40 +170,69 @@ export class RoutingEngine {
141
170
  // Found END_ROUTE - route is complete
142
171
  return {
143
172
  isRouteComplete: true,
173
+ aiContextStrings: allAiContextStrings,
144
174
  };
145
175
  }
146
176
  if (!target)
147
177
  continue;
178
+ // Evaluate skipIf condition using new system
179
+ const skipResult = await target.evaluateSkipIf(templateContext);
180
+ allAiContextStrings.push(...skipResult.aiContextStrings);
148
181
  // If target should NOT be skipped, we found our step
149
- if (!target.shouldSkip(data)) {
182
+ if (!skipResult.shouldSkip) {
150
183
  logger.debug(`[RoutingEngine] Found valid step after skipping: ${target.id}`);
151
184
  return {
152
185
  step: target,
153
186
  isRouteComplete: false,
187
+ aiContextStrings: allAiContextStrings,
154
188
  };
155
189
  }
156
190
  // Target should be skipped too - recurse deeper
157
191
  logger.debug(`[RoutingEngine] Skipping step ${target.id} (skipIf condition met), continuing traversal...`);
158
- const result = this.findFirstValidStepRecursive(target, data, visited);
192
+ const result = await this.findFirstValidStepRecursiveWithConditions(target, templateContext, visited);
193
+ // Collect AI context from recursive call
194
+ if (result.aiContextStrings) {
195
+ allAiContextStrings.push(...result.aiContextStrings);
196
+ }
159
197
  // If we found something (a valid step or END_ROUTE), return it
160
198
  if (result.step || result.isRouteComplete) {
161
- return result;
199
+ return {
200
+ ...result,
201
+ aiContextStrings: allAiContextStrings,
202
+ };
162
203
  }
163
204
  }
164
205
  // No valid steps or END_ROUTE found in this branch
165
- return {};
206
+ return { aiContextStrings: allAiContextStrings };
166
207
  }
167
208
  /**
168
- * Identify valid next candidate steps based on current step and collected data
209
+ * Identify valid next candidate steps using new condition evaluation system
169
210
  * Returns step with isRouteComplete flag if route is complete (all steps skipped + has END_ROUTE transition)
211
+ *
212
+ * NEW: Automatically completes route when all required fields are collected
170
213
  */
171
- getCandidateSteps(route, currentStep, data) {
214
+ async getCandidateStepsWithConditions(route, currentStep, templateContext) {
172
215
  const candidates = [];
216
+ const data = templateContext.data || {};
217
+ // Check if all required fields are collected
218
+ const allRequiredFieldsCollected = route.isComplete(data);
173
219
  if (!currentStep) {
220
+ // Entering route for the first time
221
+ // If all required fields already collected, route is immediately complete
222
+ if (allRequiredFieldsCollected) {
223
+ logger.debug(`[RoutingEngine] Route ${route.title} complete on entry: all required fields already collected`);
224
+ // Return a completion marker - use initial step with completion flag
225
+ candidates.push({
226
+ step: route.initialStep,
227
+ isRouteComplete: true,
228
+ });
229
+ return candidates;
230
+ }
174
231
  const initialStep = route.initialStep;
175
- if (initialStep.shouldSkip(data)) {
232
+ const skipResult = await initialStep.evaluateSkipIf(templateContext);
233
+ if (skipResult.shouldSkip) {
176
234
  // Initial step should be skipped - recursively traverse to find first non-skipped step or END_ROUTE
177
- const result = this.findFirstValidStepRecursive(initialStep, data, new Set());
235
+ const result = await this.findFirstValidStepRecursiveWithConditions(initialStep, templateContext, new Set());
178
236
  if (result.isRouteComplete) {
179
237
  // All steps are skipped and we reached END_ROUTE
180
238
  logger.debug(`[RoutingEngine] Route complete on entry: all steps skipped, END_ROUTE reached`);
@@ -200,6 +258,55 @@ export class RoutingEngine {
200
258
  }
201
259
  return candidates;
202
260
  }
261
+ // Check if all required fields are now collected (may have been collected during this step)
262
+ if (allRequiredFieldsCollected) {
263
+ // Required fields are complete - check if we should continue for optional fields
264
+ const transitions = currentStep.getTransitions();
265
+ const optionalFieldCandidates = [];
266
+ for (const transition of transitions) {
267
+ const target = transition;
268
+ // Check for END_ROUTE transition
269
+ if (target && target.id === END_ROUTE_ID) {
270
+ continue;
271
+ }
272
+ if (!target)
273
+ continue;
274
+ // Check if this step collects only optional fields
275
+ const collectsOnlyOptional = target.collect && target.collect.length > 0 &&
276
+ target.collect.every(field => route.optionalFields?.includes(field));
277
+ if (collectsOnlyOptional) {
278
+ // This step collects optional fields - it's a candidate
279
+ const skipResult = await target.evaluateSkipIf(templateContext);
280
+ if (!skipResult.shouldSkip) {
281
+ optionalFieldCandidates.push({
282
+ step: target,
283
+ isRouteComplete: false,
284
+ });
285
+ }
286
+ }
287
+ }
288
+ // If we have optional field candidates, include them along with END_ROUTE option
289
+ if (optionalFieldCandidates.length > 0) {
290
+ logger.debug(`[RoutingEngine] Required fields complete, but ${optionalFieldCandidates.length} optional field steps available`);
291
+ // Add optional field steps as candidates
292
+ candidates.push(...optionalFieldCandidates);
293
+ // Also add END_ROUTE as a candidate (AI can choose to skip optional fields)
294
+ candidates.push({
295
+ step: currentStep,
296
+ isRouteComplete: true,
297
+ });
298
+ return candidates;
299
+ }
300
+ // No optional fields to collect - route is complete
301
+ logger.debug(`[RoutingEngine] Route ${route.title} complete: all required fields collected, no optional fields remain`);
302
+ return [
303
+ {
304
+ step: currentStep,
305
+ isRouteComplete: true,
306
+ },
307
+ ];
308
+ }
309
+ // Required fields not yet complete - continue normal step progression
203
310
  const transitions = currentStep.getTransitions();
204
311
  let hasEndRoute = false;
205
312
  for (const transition of transitions) {
@@ -211,10 +318,11 @@ export class RoutingEngine {
211
318
  }
212
319
  if (!target)
213
320
  continue;
214
- if (target.shouldSkip(data)) {
321
+ const skipResult = await target.evaluateSkipIf(templateContext);
322
+ if (skipResult.shouldSkip) {
215
323
  logger.debug(`[RoutingEngine] Skipping step ${target.id} (skipIf condition met)`);
216
324
  // Recursively traverse to find next valid step or END_ROUTE
217
- const result = this.findFirstValidStepRecursive(target, data, new Set([currentStep.id]) // Already visited current step
325
+ const result = await this.findFirstValidStepRecursiveWithConditions(target, templateContext, new Set([currentStep.id]) // Already visited current step
218
326
  );
219
327
  if (result.isRouteComplete) {
220
328
  hasEndRoute = true;
@@ -247,7 +355,8 @@ export class RoutingEngine {
247
355
  ];
248
356
  }
249
357
  // Otherwise, stay in current step if it's still valid
250
- if (!currentStep.shouldSkip(data)) {
358
+ const currentSkipResult = await currentStep.evaluateSkipIf(templateContext);
359
+ if (!currentSkipResult.shouldSkip) {
251
360
  candidates.push({
252
361
  step: currentStep,
253
362
  isRouteComplete: hasEndRoute || false,
@@ -291,38 +400,69 @@ export class RoutingEngine {
291
400
  };
292
401
  }
293
402
  const lastUserMessage = getLastMessageFromHistory(history);
403
+ const templateContext = createTemplateContext({
404
+ context,
405
+ session,
406
+ history,
407
+ data: session.data
408
+ });
409
+ // Apply route filtering with new condition evaluation system
410
+ const skipIfResult = await this.filterRoutesBySkipIf(routes, templateContext);
411
+ const whenResult = await this.filterRoutesByWhen(skipIfResult.eligibleRoutes, templateContext);
412
+ // Collect all AI context strings from route conditions
413
+ const routeConditionContext = [...skipIfResult.aiContextStrings, ...whenResult.aiContextStrings];
414
+ // Use filtered routes for further processing
415
+ const eligibleRoutes = whenResult.eligibleRoutes;
416
+ logger.debug(`[RoutingEngine] Route filtering: ${routes.length} total → ${skipIfResult.eligibleRoutes.length} after skipIf → ${eligibleRoutes.length} after when`);
294
417
  let activeRouteSteps;
295
418
  let activeRoute;
296
419
  let isRouteComplete = false;
420
+ let updatedSession = session;
297
421
  if (session.currentRoute) {
298
- activeRoute = routes.find((r) => r.id === session.currentRoute?.id);
422
+ activeRoute = eligibleRoutes.find((r) => r.id === session.currentRoute?.id);
299
423
  if (activeRoute) {
300
424
  const currentStep = session.currentStep
301
425
  ? activeRoute.getStep(session.currentStep.id)
302
426
  : undefined;
303
- const candidates = this.getCandidateSteps(activeRoute, currentStep, session.data || {});
427
+ const activeTemplateContext = createTemplateContext({
428
+ ...templateContext,
429
+ session: updatedSession,
430
+ data: updatedSession.data
431
+ });
432
+ const candidates = await this.getCandidateStepsWithConditions(activeRoute, currentStep, activeTemplateContext);
304
433
  // Check if route is complete
434
+ // getCandidateStepsWithConditions now automatically handles completion when required fields are collected
305
435
  if (candidates.length === 1 && candidates[0].isRouteComplete) {
306
436
  isRouteComplete = true;
307
- logger.debug(`[RoutingEngine] Route ${activeRoute.title} is complete - all data collected`);
437
+ logger.debug(`[RoutingEngine] Route ${activeRoute.title} is complete - all required fields collected or END_ROUTE reached`);
308
438
  // Don't include steps in routing if route is complete
309
439
  activeRouteSteps = undefined;
310
440
  }
441
+ else if (candidates.length === 0) {
442
+ // No candidates - check if data is complete
443
+ const dataComplete = activeRoute.isComplete(updatedSession.data || {});
444
+ isRouteComplete = dataComplete;
445
+ logger.debug(`[RoutingEngine] Route ${activeRoute.title} has no valid steps - ` +
446
+ `marking as ${isRouteComplete ? 'complete' : 'incomplete'}`);
447
+ activeRouteSteps = undefined;
448
+ }
311
449
  else {
450
+ // Multiple candidates or single non-complete candidate
312
451
  activeRouteSteps = candidates.map((c) => c.step);
313
452
  logger.debug(`[RoutingEngine] Found ${activeRouteSteps.length} candidate steps for active route`);
314
453
  }
315
454
  }
316
455
  }
317
- const routingSchema = this.buildDynamicRoutingSchema(routes, undefined, activeRouteSteps);
456
+ const routingSchema = this.buildDynamicRoutingSchema(eligibleRoutes, undefined, activeRouteSteps);
318
457
  const routingPrompt = await this.buildRoutingPrompt({
319
458
  history,
320
- routes,
459
+ routes: eligibleRoutes,
321
460
  lastMessage: lastUserMessage,
322
461
  agentOptions,
323
462
  session,
324
463
  activeRouteSteps,
325
464
  context,
465
+ routeConditionContext, // Pass AI context strings from route conditions
326
466
  });
327
467
  const routingResult = await provider.generateMessage({
328
468
  prompt: routingPrompt,
@@ -337,19 +477,26 @@ export class RoutingEngine {
337
477
  let selectedRoute;
338
478
  let selectedStep;
339
479
  let responseDirectives;
340
- let updatedSession = session;
341
480
  if (routingResult.structured?.routes) {
342
481
  // Use cross-route completion evaluation to select optimal route
343
- const optimalRoute = this.selectOptimalRoute(routes, updatedSession.data || {}, routingResult.structured.routes);
344
- // Fall back to traditional scoring if no optimal route found
345
- selectedRoute = optimalRoute || (() => {
346
- const decision = this.decideRouteFromScores({
347
- context: routingResult.structured.context,
348
- routes: routingResult.structured.routes,
349
- responseDirectives: routingResult.structured.responseDirectives,
350
- });
351
- return routes.find((r) => r.id === decision.routeId);
352
- })();
482
+ const optimalRoute = this.selectOptimalRoute(eligibleRoutes, updatedSession.data || {}, routingResult.structured.routes);
483
+ // If no optimal route found, check why
484
+ if (!optimalRoute) {
485
+ if (eligibleRoutes.length === 0) {
486
+ // No routes passed filtering
487
+ logger.debug(`[RoutingEngine] No eligible routes available - all routes filtered out`);
488
+ selectedRoute = undefined;
489
+ }
490
+ else {
491
+ // Routes exist but selectOptimalRoute returned undefined
492
+ // This means all routes are 100% complete
493
+ logger.debug(`[RoutingEngine] No optimal route found - all ${eligibleRoutes.length} eligible routes are complete`);
494
+ selectedRoute = undefined;
495
+ }
496
+ }
497
+ else {
498
+ selectedRoute = optimalRoute;
499
+ }
353
500
  responseDirectives = routingResult.structured.responseDirectives;
354
501
  if (selectedRoute === activeRoute &&
355
502
  routingResult.structured.selectedStepId &&
@@ -374,6 +521,52 @@ export class RoutingEngine {
374
521
  completedRoutes,
375
522
  };
376
523
  }
524
+ /**
525
+ * Filter routes based on skipIf conditions
526
+ * @param routes - All available routes
527
+ * @param templateContext - Context for condition evaluation
528
+ * @returns Object with eligible routes and collected AI context strings
529
+ */
530
+ async filterRoutesBySkipIf(routes, templateContext) {
531
+ const eligibleRoutes = [];
532
+ const aiContextStrings = [];
533
+ for (const route of routes) {
534
+ const skipResult = await route.evaluateSkipIf(templateContext);
535
+ // Collect AI context strings from skipIf conditions
536
+ aiContextStrings.push(...skipResult.aiContextStrings);
537
+ // If route should not be skipped, it's eligible
538
+ if (!skipResult.programmaticResult) {
539
+ eligibleRoutes.push(route);
540
+ }
541
+ else {
542
+ logger.debug(`[RoutingEngine] Skipping route ${route.title} (skipIf condition met)`);
543
+ }
544
+ }
545
+ return { eligibleRoutes, aiContextStrings };
546
+ }
547
+ /**
548
+ * Filter routes based on when conditions
549
+ * @param routes - Routes that passed skipIf filtering
550
+ * @param templateContext - Context for condition evaluation
551
+ * @returns Object with eligible routes and collected AI context strings
552
+ */
553
+ async filterRoutesByWhen(routes, templateContext) {
554
+ const eligibleRoutes = [];
555
+ const aiContextStrings = [];
556
+ for (const route of routes) {
557
+ const whenResult = await route.evaluateWhen(templateContext);
558
+ // Collect AI context strings from when conditions
559
+ aiContextStrings.push(...whenResult.aiContextStrings);
560
+ // If route has no programmatic conditions or they evaluate to true, it's eligible
561
+ if (!whenResult.hasProgrammaticConditions || whenResult.programmaticResult) {
562
+ eligibleRoutes.push(route);
563
+ }
564
+ else {
565
+ logger.debug(`[RoutingEngine] Route ${route.title} not eligible (when condition not met)`);
566
+ }
567
+ }
568
+ return { eligibleRoutes, aiContextStrings };
569
+ }
377
570
  /**
378
571
  * Evaluate all routes for completion based on collected data
379
572
  * @param routes - All available routes
@@ -400,6 +593,7 @@ export class RoutingEngine {
400
593
  /**
401
594
  * Find the best route to continue based on completion status and user intent
402
595
  * Prioritizes routes that are partially complete but not finished
596
+ * IMPORTANT: Completed routes are excluded to prevent re-entering finished tasks
403
597
  * @param routes - All available routes
404
598
  * @param data - Currently collected agent-level data
405
599
  * @param routeScores - AI-generated route scores from routing decision
@@ -412,8 +606,10 @@ export class RoutingEngine {
412
606
  for (const route of routes) {
413
607
  const aiScore = routeScores[route.id] || 0;
414
608
  const completionProgress = completionStatus.get(route.id) || 0;
415
- // Skip fully completed routes unless they have very high AI scores
416
- if (completionProgress >= 1.0 && aiScore < 80) {
609
+ // ALWAYS skip fully completed routes to prevent re-entering finished tasks
610
+ // Users should not be forced back into completed routes
611
+ if (completionProgress >= 1.0) {
612
+ logger.debug(`[RoutingEngine] Excluding completed route: ${route.title} (100% complete)`);
417
613
  continue;
418
614
  }
419
615
  // Boost partially complete routes that match user intent
@@ -440,8 +636,8 @@ export class RoutingEngine {
440
636
  * @private
441
637
  */
442
638
  async buildStepSelectionPrompt(params) {
443
- const { route, currentStep, candidates, data, history, lastMessage, agentOptions, context, session, } = params;
444
- const templateContext = { context, session, history };
639
+ const { route, currentStep, candidates, data, history, lastMessage, agentOptions, context, session, stepConditionContext, includeEndRoute = false, } = params;
640
+ const templateContext = createTemplateContext({ context, session, history });
445
641
  const pc = new PromptComposer(templateContext);
446
642
  // Add agent metadata
447
643
  if (agentOptions) {
@@ -466,7 +662,7 @@ export class RoutingEngine {
466
662
  // Add conversation history
467
663
  await pc.addInteractionHistory(history);
468
664
  await pc.addLastMessage(lastMessage);
469
- // Add candidate steps
665
+ // Add candidate steps with condition context
470
666
  const stepDescriptions = [];
471
667
  for (const candidate of candidates) {
472
668
  const idx = candidates.indexOf(candidate);
@@ -474,9 +670,15 @@ export class RoutingEngine {
474
670
  `${idx + 1}. Step ID: ${candidate.step.id}`,
475
671
  ` Description: ${candidate.step.description || "N/A"}`,
476
672
  ];
673
+ // Add when condition context
477
674
  if (candidate.step.when) {
478
- const renderedWhen = await render(candidate.step.when, templateContext);
479
- parts.push(` When this step should be completed: ${renderedWhen}`);
675
+ const whenResult = await candidate.step.evaluateWhen(templateContext);
676
+ if (whenResult.aiContextStrings.length > 0) {
677
+ parts.push(` When conditions: ${whenResult.aiContextStrings.join(", ")}`);
678
+ }
679
+ else if (typeof candidate.step.when === 'string') {
680
+ parts.push(` When this step should be completed: ${candidate.step.when}`);
681
+ }
480
682
  }
481
683
  if (candidate.step.requires && candidate.step.requires.length > 0) {
482
684
  parts.push(` Required Data: ${candidate.step.requires.join(", ")}`);
@@ -487,8 +689,18 @@ export class RoutingEngine {
487
689
  stepDescriptions.push(parts.join("\n"));
488
690
  }
489
691
  await pc.addInstruction(`Available Steps to Transition To:\n${stepDescriptions.join("\n\n")}`);
692
+ // Add step condition context if available
693
+ if (stepConditionContext && stepConditionContext.length > 0) {
694
+ await pc.addInstruction([
695
+ "",
696
+ "Additional step context from conditions:",
697
+ ...stepConditionContext.map(ctx => `- ${ctx}`),
698
+ "",
699
+ "Consider this context when selecting the most appropriate step.",
700
+ ].join("\n"));
701
+ }
490
702
  // Add decision prompt
491
- await pc.addInstruction([
703
+ const decisionRules = [
492
704
  "Task: Decide which step to transition to based on:",
493
705
  "1. The user's current message and intent",
494
706
  "2. The conversation history and context",
@@ -501,16 +713,24 @@ export class RoutingEngine {
501
713
  "- If a step requires data we don't have, consider if we should collect it now",
502
714
  "- Choose the step that makes the most sense for moving the conversation forward",
503
715
  "- Steps with skipIf conditions that are met have already been filtered out",
504
- "",
505
- "Return ONLY JSON matching the provided schema.",
506
- ].join("\n"));
716
+ ];
717
+ if (includeEndRoute) {
718
+ decisionRules.push("", `- You can select '${END_ROUTE_ID}' to complete this route if:`, " * All required data has been collected", " * The user's intent suggests they're done with this task", " * No further steps are needed to fulfill the user's request");
719
+ }
720
+ decisionRules.push("", "Return ONLY JSON matching the provided schema.");
721
+ await pc.addInstruction(decisionRules.join("\n"));
507
722
  return pc.build();
508
723
  }
509
724
  /**
510
725
  * Build schema for step selection
511
726
  * @private
512
727
  */
513
- buildStepSelectionSchema(validSteps) {
728
+ buildStepSelectionSchema(validSteps, includeEndRoute = false) {
729
+ const stepIds = validSteps.map((s) => s.id);
730
+ // Add END_ROUTE as an option if requested (when required fields are complete)
731
+ if (includeEndRoute) {
732
+ stepIds.push(END_ROUTE_ID);
733
+ }
514
734
  return {
515
735
  description: "Step transition decision based on conversation context and collected data",
516
736
  type: "object",
@@ -523,8 +743,10 @@ export class RoutingEngine {
523
743
  selectedStepId: {
524
744
  type: "string",
525
745
  nullable: false,
526
- description: "The ID of the selected step to transition to",
527
- enum: validSteps.map((s) => s.id),
746
+ description: includeEndRoute
747
+ ? `The ID of the selected step to transition to, or '${END_ROUTE_ID}' to complete the route`
748
+ : "The ID of the selected step to transition to",
749
+ enum: stepIds,
528
750
  },
529
751
  responseDirectives: {
530
752
  type: "array",
@@ -600,8 +822,8 @@ export class RoutingEngine {
600
822
  return base;
601
823
  }
602
824
  async buildRoutingPrompt(params) {
603
- const { history, routes, lastMessage, agentOptions, session, activeRouteSteps, context, } = params;
604
- const templateContext = { context, session, history };
825
+ const { history, routes, lastMessage, agentOptions, session, activeRouteSteps, context, routeConditionContext, } = params;
826
+ const templateContext = createTemplateContext({ context, session, history });
605
827
  const pc = new PromptComposer(templateContext);
606
828
  if (agentOptions) {
607
829
  await pc.addAgentMeta(agentOptions);
@@ -653,15 +875,23 @@ export class RoutingEngine {
653
875
  "",
654
876
  "Available steps in active route (choose one to transition to):",
655
877
  ];
878
+ const activeStepConditionContext = [];
656
879
  for (const step of activeRouteSteps) {
657
880
  const idx = activeRouteSteps.indexOf(step);
658
881
  stepInfo.push(`${idx + 1}. Step: ${step.id}`);
659
882
  if (step.description) {
660
883
  stepInfo.push(` Description: ${step.description}`);
661
884
  }
662
- const renderedWhen = await render(step.when, templateContext);
885
+ // Collect AI context from step conditions
663
886
  if (step.when) {
664
- stepInfo.push(` When this step should be completed: ${renderedWhen}`);
887
+ const whenResult = await step.evaluateWhen(templateContext);
888
+ if (whenResult.aiContextStrings.length > 0) {
889
+ stepInfo.push(` When conditions: ${whenResult.aiContextStrings.join(", ")}`);
890
+ activeStepConditionContext.push(...whenResult.aiContextStrings);
891
+ }
892
+ else if (typeof step.when === 'string') {
893
+ stepInfo.push(` When this step should be completed: ${step.when}`);
894
+ }
665
895
  }
666
896
  if (step.requires && step.requires.length > 0) {
667
897
  stepInfo.push(` Required data: ${step.requires.join(", ")}`);
@@ -677,11 +907,31 @@ export class RoutingEngine {
677
907
  stepInfo.push("- The logical next step in the conversation");
678
908
  stepInfo.push("- Whether conditions for steps are met");
679
909
  await pc.addInstruction(stepInfo.join("\n"));
910
+ // Add active step condition context if available
911
+ if (activeStepConditionContext.length > 0) {
912
+ await pc.addInstruction([
913
+ "",
914
+ "Additional context from step conditions:",
915
+ ...activeStepConditionContext.map(ctx => `- ${ctx}`),
916
+ "",
917
+ "Use this context to inform your step selection decision.",
918
+ ].join("\n"));
919
+ }
680
920
  }
681
921
  }
682
922
  await pc.addInteractionHistory(history);
683
923
  await pc.addLastMessage(lastMessage);
684
924
  await pc.addRoutingOverview(routes);
925
+ // Add route condition context if available
926
+ if (routeConditionContext && routeConditionContext.length > 0) {
927
+ await pc.addInstruction([
928
+ "",
929
+ "Additional routing context from route conditions:",
930
+ ...routeConditionContext.map(ctx => `- ${ctx}`),
931
+ "",
932
+ "Consider this context when scoring routes for relevance.",
933
+ ].join("\n"));
934
+ }
685
935
  await pc.addInstruction([
686
936
  "Scoring rules:",
687
937
  "- 90-100: explicit keywords + clear intent",