@falai/agent 0.1.0-alpha2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. package/README.md +797 -0
  2. package/dist/cjs/package.json +1 -0
  3. package/dist/cjs/src/adapters/MemoryAdapter.d.ts +47 -0
  4. package/dist/cjs/src/adapters/MemoryAdapter.d.ts.map +1 -0
  5. package/dist/cjs/src/adapters/MemoryAdapter.js +202 -0
  6. package/dist/cjs/src/adapters/MemoryAdapter.js.map +1 -0
  7. package/dist/cjs/src/adapters/MongoAdapter.d.ts +97 -0
  8. package/dist/cjs/src/adapters/MongoAdapter.d.ts.map +1 -0
  9. package/dist/cjs/src/adapters/MongoAdapter.js +168 -0
  10. package/dist/cjs/src/adapters/MongoAdapter.js.map +1 -0
  11. package/dist/cjs/src/adapters/OpenSearchAdapter.d.ts +169 -0
  12. package/dist/cjs/src/adapters/OpenSearchAdapter.d.ts.map +1 -0
  13. package/dist/cjs/src/adapters/OpenSearchAdapter.js +458 -0
  14. package/dist/cjs/src/adapters/OpenSearchAdapter.js.map +1 -0
  15. package/dist/cjs/src/adapters/PostgreSQLAdapter.d.ts +71 -0
  16. package/dist/cjs/src/adapters/PostgreSQLAdapter.d.ts.map +1 -0
  17. package/dist/cjs/src/adapters/PostgreSQLAdapter.js +260 -0
  18. package/dist/cjs/src/adapters/PostgreSQLAdapter.js.map +1 -0
  19. package/dist/cjs/src/adapters/PrismaAdapter.d.ts +115 -0
  20. package/dist/cjs/src/adapters/PrismaAdapter.d.ts.map +1 -0
  21. package/dist/cjs/src/adapters/PrismaAdapter.js +366 -0
  22. package/dist/cjs/src/adapters/PrismaAdapter.js.map +1 -0
  23. package/dist/cjs/src/adapters/RedisAdapter.d.ts +71 -0
  24. package/dist/cjs/src/adapters/RedisAdapter.d.ts.map +1 -0
  25. package/dist/cjs/src/adapters/RedisAdapter.js +231 -0
  26. package/dist/cjs/src/adapters/RedisAdapter.js.map +1 -0
  27. package/dist/cjs/src/adapters/SQLiteAdapter.d.ts +69 -0
  28. package/dist/cjs/src/adapters/SQLiteAdapter.d.ts.map +1 -0
  29. package/dist/cjs/src/adapters/SQLiteAdapter.js +312 -0
  30. package/dist/cjs/src/adapters/SQLiteAdapter.js.map +1 -0
  31. package/dist/cjs/src/adapters/index.d.ts +17 -0
  32. package/dist/cjs/src/adapters/index.d.ts.map +1 -0
  33. package/dist/cjs/src/adapters/index.js +21 -0
  34. package/dist/cjs/src/adapters/index.js.map +1 -0
  35. package/dist/cjs/src/constants/index.d.ts +10 -0
  36. package/dist/cjs/src/constants/index.d.ts.map +1 -0
  37. package/dist/cjs/src/constants/index.js +13 -0
  38. package/dist/cjs/src/constants/index.js.map +1 -0
  39. package/dist/cjs/src/core/Agent.d.ts +232 -0
  40. package/dist/cjs/src/core/Agent.d.ts.map +1 -0
  41. package/dist/cjs/src/core/Agent.js +741 -0
  42. package/dist/cjs/src/core/Agent.js.map +1 -0
  43. package/dist/cjs/src/core/Events.d.ts +26 -0
  44. package/dist/cjs/src/core/Events.d.ts.map +1 -0
  45. package/dist/cjs/src/core/Events.js +144 -0
  46. package/dist/cjs/src/core/Events.js.map +1 -0
  47. package/dist/cjs/src/core/PersistenceManager.d.ts +98 -0
  48. package/dist/cjs/src/core/PersistenceManager.d.ts.map +1 -0
  49. package/dist/cjs/src/core/PersistenceManager.js +261 -0
  50. package/dist/cjs/src/core/PersistenceManager.js.map +1 -0
  51. package/dist/cjs/src/core/PromptComposer.d.ts +27 -0
  52. package/dist/cjs/src/core/PromptComposer.d.ts.map +1 -0
  53. package/dist/cjs/src/core/PromptComposer.js +194 -0
  54. package/dist/cjs/src/core/PromptComposer.js.map +1 -0
  55. package/dist/cjs/src/core/ResponseEngine.d.ts +32 -0
  56. package/dist/cjs/src/core/ResponseEngine.d.ts.map +1 -0
  57. package/dist/cjs/src/core/ResponseEngine.js +202 -0
  58. package/dist/cjs/src/core/ResponseEngine.js.map +1 -0
  59. package/dist/cjs/src/core/ResponseModal.d.ts +222 -0
  60. package/dist/cjs/src/core/ResponseModal.d.ts.map +1 -0
  61. package/dist/cjs/src/core/ResponseModal.js +1588 -0
  62. package/dist/cjs/src/core/ResponseModal.js.map +1 -0
  63. package/dist/cjs/src/core/ResponsePipeline.d.ts +175 -0
  64. package/dist/cjs/src/core/ResponsePipeline.d.ts.map +1 -0
  65. package/dist/cjs/src/core/ResponsePipeline.js +549 -0
  66. package/dist/cjs/src/core/ResponsePipeline.js.map +1 -0
  67. package/dist/cjs/src/core/Route.d.ts +181 -0
  68. package/dist/cjs/src/core/Route.d.ts.map +1 -0
  69. package/dist/cjs/src/core/Route.js +541 -0
  70. package/dist/cjs/src/core/Route.js.map +1 -0
  71. package/dist/cjs/src/core/RoutingEngine.d.ts +159 -0
  72. package/dist/cjs/src/core/RoutingEngine.d.ts.map +1 -0
  73. package/dist/cjs/src/core/RoutingEngine.js +961 -0
  74. package/dist/cjs/src/core/RoutingEngine.js.map +1 -0
  75. package/dist/cjs/src/core/SessionManager.d.ts +94 -0
  76. package/dist/cjs/src/core/SessionManager.d.ts.map +1 -0
  77. package/dist/cjs/src/core/SessionManager.js +239 -0
  78. package/dist/cjs/src/core/SessionManager.js.map +1 -0
  79. package/dist/cjs/src/core/Step.d.ts +170 -0
  80. package/dist/cjs/src/core/Step.d.ts.map +1 -0
  81. package/dist/cjs/src/core/Step.js +448 -0
  82. package/dist/cjs/src/core/Step.js.map +1 -0
  83. package/dist/cjs/src/core/ToolManager.d.ts +234 -0
  84. package/dist/cjs/src/core/ToolManager.d.ts.map +1 -0
  85. package/dist/cjs/src/core/ToolManager.js +1117 -0
  86. package/dist/cjs/src/core/ToolManager.js.map +1 -0
  87. package/dist/cjs/src/index.d.ts +44 -0
  88. package/dist/cjs/src/index.d.ts.map +1 -0
  89. package/dist/cjs/src/index.js +88 -0
  90. package/dist/cjs/src/index.js.map +1 -0
  91. package/dist/cjs/src/providers/AnthropicProvider.d.ts +43 -0
  92. package/dist/cjs/src/providers/AnthropicProvider.d.ts.map +1 -0
  93. package/dist/cjs/src/providers/AnthropicProvider.js +377 -0
  94. package/dist/cjs/src/providers/AnthropicProvider.js.map +1 -0
  95. package/dist/cjs/src/providers/GeminiProvider.d.ts +58 -0
  96. package/dist/cjs/src/providers/GeminiProvider.d.ts.map +1 -0
  97. package/dist/cjs/src/providers/GeminiProvider.js +489 -0
  98. package/dist/cjs/src/providers/GeminiProvider.js.map +1 -0
  99. package/dist/cjs/src/providers/OpenAIProvider.d.ts +52 -0
  100. package/dist/cjs/src/providers/OpenAIProvider.d.ts.map +1 -0
  101. package/dist/cjs/src/providers/OpenAIProvider.js +395 -0
  102. package/dist/cjs/src/providers/OpenAIProvider.js.map +1 -0
  103. package/dist/cjs/src/providers/OpenRouterProvider.d.ts +56 -0
  104. package/dist/cjs/src/providers/OpenRouterProvider.d.ts.map +1 -0
  105. package/dist/cjs/src/providers/OpenRouterProvider.js +409 -0
  106. package/dist/cjs/src/providers/OpenRouterProvider.js.map +1 -0
  107. package/dist/cjs/src/providers/index.d.ts +13 -0
  108. package/dist/cjs/src/providers/index.d.ts.map +1 -0
  109. package/dist/cjs/src/providers/index.js +16 -0
  110. package/dist/cjs/src/providers/index.js.map +1 -0
  111. package/dist/cjs/src/types/agent.d.ts +181 -0
  112. package/dist/cjs/src/types/agent.d.ts.map +1 -0
  113. package/dist/cjs/src/types/agent.js +21 -0
  114. package/dist/cjs/src/types/agent.js.map +1 -0
  115. package/dist/cjs/src/types/ai.d.ts +143 -0
  116. package/dist/cjs/src/types/ai.d.ts.map +1 -0
  117. package/dist/cjs/src/types/ai.js +6 -0
  118. package/dist/cjs/src/types/ai.js.map +1 -0
  119. package/dist/cjs/src/types/history.d.ts +178 -0
  120. package/dist/cjs/src/types/history.d.ts.map +1 -0
  121. package/dist/cjs/src/types/history.js +33 -0
  122. package/dist/cjs/src/types/history.js.map +1 -0
  123. package/dist/cjs/src/types/index.d.ts +22 -0
  124. package/dist/cjs/src/types/index.d.ts.map +1 -0
  125. package/dist/cjs/src/types/index.js +37 -0
  126. package/dist/cjs/src/types/index.js.map +1 -0
  127. package/dist/cjs/src/types/persistence.d.ts +209 -0
  128. package/dist/cjs/src/types/persistence.d.ts.map +1 -0
  129. package/dist/cjs/src/types/persistence.js +7 -0
  130. package/dist/cjs/src/types/persistence.js.map +1 -0
  131. package/dist/cjs/src/types/route.d.ts +238 -0
  132. package/dist/cjs/src/types/route.d.ts.map +1 -0
  133. package/dist/cjs/src/types/route.js +6 -0
  134. package/dist/cjs/src/types/route.js.map +1 -0
  135. package/dist/cjs/src/types/routing.d.ts +16 -0
  136. package/dist/cjs/src/types/routing.d.ts.map +1 -0
  137. package/dist/cjs/src/types/routing.js +3 -0
  138. package/dist/cjs/src/types/routing.js.map +1 -0
  139. package/dist/cjs/src/types/schema.d.ts +22 -0
  140. package/dist/cjs/src/types/schema.d.ts.map +1 -0
  141. package/dist/cjs/src/types/schema.js +3 -0
  142. package/dist/cjs/src/types/schema.js.map +1 -0
  143. package/dist/cjs/src/types/session.d.ts +65 -0
  144. package/dist/cjs/src/types/session.d.ts.map +1 -0
  145. package/dist/cjs/src/types/session.js +6 -0
  146. package/dist/cjs/src/types/session.js.map +1 -0
  147. package/dist/cjs/src/types/template.d.ts +88 -0
  148. package/dist/cjs/src/types/template.d.ts.map +1 -0
  149. package/dist/cjs/src/types/template.js +3 -0
  150. package/dist/cjs/src/types/template.js.map +1 -0
  151. package/dist/cjs/src/types/tool.d.ts +130 -0
  152. package/dist/cjs/src/types/tool.d.ts.map +1 -0
  153. package/dist/cjs/src/types/tool.js +19 -0
  154. package/dist/cjs/src/types/tool.js.map +1 -0
  155. package/dist/cjs/src/utils/clone.d.ts +8 -0
  156. package/dist/cjs/src/utils/clone.d.ts.map +1 -0
  157. package/dist/cjs/src/utils/clone.js +32 -0
  158. package/dist/cjs/src/utils/clone.js.map +1 -0
  159. package/dist/cjs/src/utils/condition.d.ts +38 -0
  160. package/dist/cjs/src/utils/condition.d.ts.map +1 -0
  161. package/dist/cjs/src/utils/condition.js +168 -0
  162. package/dist/cjs/src/utils/condition.js.map +1 -0
  163. package/dist/cjs/src/utils/event.d.ts +6 -0
  164. package/dist/cjs/src/utils/event.d.ts.map +1 -0
  165. package/dist/cjs/src/utils/event.js +20 -0
  166. package/dist/cjs/src/utils/event.js.map +1 -0
  167. package/dist/cjs/src/utils/history.d.ts +60 -0
  168. package/dist/cjs/src/utils/history.d.ts.map +1 -0
  169. package/dist/cjs/src/utils/history.js +274 -0
  170. package/dist/cjs/src/utils/history.js.map +1 -0
  171. package/dist/cjs/src/utils/id.d.ts +25 -0
  172. package/dist/cjs/src/utils/id.d.ts.map +1 -0
  173. package/dist/cjs/src/utils/id.js +70 -0
  174. package/dist/cjs/src/utils/id.js.map +1 -0
  175. package/dist/cjs/src/utils/index.d.ts +15 -0
  176. package/dist/cjs/src/utils/index.d.ts.map +1 -0
  177. package/dist/cjs/src/utils/index.js +64 -0
  178. package/dist/cjs/src/utils/index.js.map +1 -0
  179. package/dist/cjs/src/utils/json.d.ts +16 -0
  180. package/dist/cjs/src/utils/json.d.ts.map +1 -0
  181. package/dist/cjs/src/utils/json.js +47 -0
  182. package/dist/cjs/src/utils/json.js.map +1 -0
  183. package/dist/cjs/src/utils/logger.d.ts +10 -0
  184. package/dist/cjs/src/utils/logger.d.ts.map +1 -0
  185. package/dist/cjs/src/utils/logger.js +23 -0
  186. package/dist/cjs/src/utils/logger.js.map +1 -0
  187. package/dist/cjs/src/utils/retry.d.ts +10 -0
  188. package/dist/cjs/src/utils/retry.d.ts.map +1 -0
  189. package/dist/cjs/src/utils/retry.js +76 -0
  190. package/dist/cjs/src/utils/retry.js.map +1 -0
  191. package/dist/cjs/src/utils/session.d.ts +51 -0
  192. package/dist/cjs/src/utils/session.d.ts.map +1 -0
  193. package/dist/cjs/src/utils/session.js +170 -0
  194. package/dist/cjs/src/utils/session.js.map +1 -0
  195. package/dist/cjs/src/utils/template.d.ts +155 -0
  196. package/dist/cjs/src/utils/template.d.ts.map +1 -0
  197. package/dist/cjs/src/utils/template.js +383 -0
  198. package/dist/cjs/src/utils/template.js.map +1 -0
  199. package/dist/src/adapters/MemoryAdapter.d.ts +47 -0
  200. package/dist/src/adapters/MemoryAdapter.d.ts.map +1 -0
  201. package/dist/src/adapters/MemoryAdapter.js +198 -0
  202. package/dist/src/adapters/MemoryAdapter.js.map +1 -0
  203. package/dist/src/adapters/MongoAdapter.d.ts +97 -0
  204. package/dist/src/adapters/MongoAdapter.d.ts.map +1 -0
  205. package/dist/src/adapters/MongoAdapter.js +164 -0
  206. package/dist/src/adapters/MongoAdapter.js.map +1 -0
  207. package/dist/src/adapters/OpenSearchAdapter.d.ts +169 -0
  208. package/dist/src/adapters/OpenSearchAdapter.d.ts.map +1 -0
  209. package/dist/src/adapters/OpenSearchAdapter.js +454 -0
  210. package/dist/src/adapters/OpenSearchAdapter.js.map +1 -0
  211. package/dist/src/adapters/PostgreSQLAdapter.d.ts +71 -0
  212. package/dist/src/adapters/PostgreSQLAdapter.d.ts.map +1 -0
  213. package/dist/src/adapters/PostgreSQLAdapter.js +256 -0
  214. package/dist/src/adapters/PostgreSQLAdapter.js.map +1 -0
  215. package/dist/src/adapters/PrismaAdapter.d.ts +115 -0
  216. package/dist/src/adapters/PrismaAdapter.d.ts.map +1 -0
  217. package/dist/src/adapters/PrismaAdapter.js +362 -0
  218. package/dist/src/adapters/PrismaAdapter.js.map +1 -0
  219. package/dist/src/adapters/RedisAdapter.d.ts +71 -0
  220. package/dist/src/adapters/RedisAdapter.d.ts.map +1 -0
  221. package/dist/src/adapters/RedisAdapter.js +227 -0
  222. package/dist/src/adapters/RedisAdapter.js.map +1 -0
  223. package/dist/src/adapters/SQLiteAdapter.d.ts +69 -0
  224. package/dist/src/adapters/SQLiteAdapter.d.ts.map +1 -0
  225. package/dist/src/adapters/SQLiteAdapter.js +308 -0
  226. package/dist/src/adapters/SQLiteAdapter.js.map +1 -0
  227. package/dist/src/adapters/index.d.ts +17 -0
  228. package/dist/src/adapters/index.d.ts.map +1 -0
  229. package/dist/src/adapters/index.js +11 -0
  230. package/dist/src/adapters/index.js.map +1 -0
  231. package/dist/src/constants/index.d.ts +10 -0
  232. package/dist/src/constants/index.d.ts.map +1 -0
  233. package/dist/src/constants/index.js +10 -0
  234. package/dist/src/constants/index.js.map +1 -0
  235. package/dist/src/core/Agent.d.ts +232 -0
  236. package/dist/src/core/Agent.d.ts.map +1 -0
  237. package/dist/src/core/Agent.js +737 -0
  238. package/dist/src/core/Agent.js.map +1 -0
  239. package/dist/src/core/Events.d.ts +26 -0
  240. package/dist/src/core/Events.d.ts.map +1 -0
  241. package/dist/src/core/Events.js +137 -0
  242. package/dist/src/core/Events.js.map +1 -0
  243. package/dist/src/core/PersistenceManager.d.ts +98 -0
  244. package/dist/src/core/PersistenceManager.d.ts.map +1 -0
  245. package/dist/src/core/PersistenceManager.js +257 -0
  246. package/dist/src/core/PersistenceManager.js.map +1 -0
  247. package/dist/src/core/PromptComposer.d.ts +27 -0
  248. package/dist/src/core/PromptComposer.d.ts.map +1 -0
  249. package/dist/src/core/PromptComposer.js +190 -0
  250. package/dist/src/core/PromptComposer.js.map +1 -0
  251. package/dist/src/core/ResponseEngine.d.ts +32 -0
  252. package/dist/src/core/ResponseEngine.d.ts.map +1 -0
  253. package/dist/src/core/ResponseEngine.js +198 -0
  254. package/dist/src/core/ResponseEngine.js.map +1 -0
  255. package/dist/src/core/ResponseModal.d.ts +222 -0
  256. package/dist/src/core/ResponseModal.d.ts.map +1 -0
  257. package/dist/src/core/ResponseModal.js +1583 -0
  258. package/dist/src/core/ResponseModal.js.map +1 -0
  259. package/dist/src/core/ResponsePipeline.d.ts +175 -0
  260. package/dist/src/core/ResponsePipeline.d.ts.map +1 -0
  261. package/dist/src/core/ResponsePipeline.js +545 -0
  262. package/dist/src/core/ResponsePipeline.js.map +1 -0
  263. package/dist/src/core/Route.d.ts +181 -0
  264. package/dist/src/core/Route.d.ts.map +1 -0
  265. package/dist/src/core/Route.js +537 -0
  266. package/dist/src/core/Route.js.map +1 -0
  267. package/dist/src/core/RoutingEngine.d.ts +159 -0
  268. package/dist/src/core/RoutingEngine.d.ts.map +1 -0
  269. package/dist/src/core/RoutingEngine.js +957 -0
  270. package/dist/src/core/RoutingEngine.js.map +1 -0
  271. package/dist/src/core/SessionManager.d.ts +94 -0
  272. package/dist/src/core/SessionManager.d.ts.map +1 -0
  273. package/dist/src/core/SessionManager.js +235 -0
  274. package/dist/src/core/SessionManager.js.map +1 -0
  275. package/dist/src/core/Step.d.ts +170 -0
  276. package/dist/src/core/Step.d.ts.map +1 -0
  277. package/dist/src/core/Step.js +444 -0
  278. package/dist/src/core/Step.js.map +1 -0
  279. package/dist/src/core/ToolManager.d.ts +234 -0
  280. package/dist/src/core/ToolManager.d.ts.map +1 -0
  281. package/dist/src/core/ToolManager.js +1111 -0
  282. package/dist/src/core/ToolManager.js.map +1 -0
  283. package/dist/src/index.d.ts +44 -0
  284. package/dist/src/index.d.ts.map +1 -0
  285. package/dist/src/index.js +37 -0
  286. package/dist/src/index.js.map +1 -0
  287. package/dist/src/providers/AnthropicProvider.d.ts +43 -0
  288. package/dist/src/providers/AnthropicProvider.d.ts.map +1 -0
  289. package/dist/src/providers/AnthropicProvider.js +370 -0
  290. package/dist/src/providers/AnthropicProvider.js.map +1 -0
  291. package/dist/src/providers/GeminiProvider.d.ts +58 -0
  292. package/dist/src/providers/GeminiProvider.d.ts.map +1 -0
  293. package/dist/src/providers/GeminiProvider.js +485 -0
  294. package/dist/src/providers/GeminiProvider.js.map +1 -0
  295. package/dist/src/providers/OpenAIProvider.d.ts +52 -0
  296. package/dist/src/providers/OpenAIProvider.d.ts.map +1 -0
  297. package/dist/src/providers/OpenAIProvider.js +388 -0
  298. package/dist/src/providers/OpenAIProvider.js.map +1 -0
  299. package/dist/src/providers/OpenRouterProvider.d.ts +56 -0
  300. package/dist/src/providers/OpenRouterProvider.d.ts.map +1 -0
  301. package/dist/src/providers/OpenRouterProvider.js +402 -0
  302. package/dist/src/providers/OpenRouterProvider.js.map +1 -0
  303. package/dist/src/providers/index.d.ts +13 -0
  304. package/dist/src/providers/index.d.ts.map +1 -0
  305. package/dist/src/providers/index.js +9 -0
  306. package/dist/src/providers/index.js.map +1 -0
  307. package/dist/src/types/agent.d.ts +181 -0
  308. package/dist/src/types/agent.d.ts.map +1 -0
  309. package/dist/src/types/agent.js +18 -0
  310. package/dist/src/types/agent.js.map +1 -0
  311. package/dist/src/types/ai.d.ts +143 -0
  312. package/dist/src/types/ai.d.ts.map +1 -0
  313. package/dist/src/types/ai.js +5 -0
  314. package/dist/src/types/ai.js.map +1 -0
  315. package/dist/src/types/history.d.ts +178 -0
  316. package/dist/src/types/history.d.ts.map +1 -0
  317. package/dist/src/types/history.js +30 -0
  318. package/dist/src/types/history.js.map +1 -0
  319. package/dist/src/types/index.d.ts +22 -0
  320. package/dist/src/types/index.d.ts.map +1 -0
  321. package/dist/src/types/index.js +12 -0
  322. package/dist/src/types/index.js.map +1 -0
  323. package/dist/src/types/persistence.d.ts +209 -0
  324. package/dist/src/types/persistence.d.ts.map +1 -0
  325. package/dist/src/types/persistence.js +6 -0
  326. package/dist/src/types/persistence.js.map +1 -0
  327. package/dist/src/types/route.d.ts +238 -0
  328. package/dist/src/types/route.d.ts.map +1 -0
  329. package/dist/src/types/route.js +5 -0
  330. package/dist/src/types/route.js.map +1 -0
  331. package/dist/src/types/routing.d.ts +16 -0
  332. package/dist/src/types/routing.d.ts.map +1 -0
  333. package/dist/src/types/routing.js +2 -0
  334. package/dist/src/types/routing.js.map +1 -0
  335. package/dist/src/types/schema.d.ts +22 -0
  336. package/dist/src/types/schema.d.ts.map +1 -0
  337. package/dist/src/types/schema.js +2 -0
  338. package/dist/src/types/schema.js.map +1 -0
  339. package/dist/src/types/session.d.ts +65 -0
  340. package/dist/src/types/session.d.ts.map +1 -0
  341. package/dist/src/types/session.js +5 -0
  342. package/dist/src/types/session.js.map +1 -0
  343. package/dist/src/types/template.d.ts +88 -0
  344. package/dist/src/types/template.d.ts.map +1 -0
  345. package/dist/src/types/template.js +2 -0
  346. package/dist/src/types/template.js.map +1 -0
  347. package/dist/src/types/tool.d.ts +130 -0
  348. package/dist/src/types/tool.d.ts.map +1 -0
  349. package/dist/src/types/tool.js +16 -0
  350. package/dist/src/types/tool.js.map +1 -0
  351. package/dist/src/utils/clone.d.ts +8 -0
  352. package/dist/src/utils/clone.d.ts.map +1 -0
  353. package/dist/src/utils/clone.js +29 -0
  354. package/dist/src/utils/clone.js.map +1 -0
  355. package/dist/src/utils/condition.d.ts +38 -0
  356. package/dist/src/utils/condition.d.ts.map +1 -0
  357. package/dist/src/utils/condition.js +161 -0
  358. package/dist/src/utils/condition.js.map +1 -0
  359. package/dist/src/utils/event.d.ts +6 -0
  360. package/dist/src/utils/event.d.ts.map +1 -0
  361. package/dist/src/utils/event.js +17 -0
  362. package/dist/src/utils/event.js.map +1 -0
  363. package/dist/src/utils/history.d.ts +60 -0
  364. package/dist/src/utils/history.d.ts.map +1 -0
  365. package/dist/src/utils/history.js +263 -0
  366. package/dist/src/utils/history.js.map +1 -0
  367. package/dist/src/utils/id.d.ts +25 -0
  368. package/dist/src/utils/id.d.ts.map +1 -0
  369. package/dist/src/utils/id.js +64 -0
  370. package/dist/src/utils/id.js.map +1 -0
  371. package/dist/src/utils/index.d.ts +15 -0
  372. package/dist/src/utils/index.d.ts.map +1 -0
  373. package/dist/src/utils/index.js +23 -0
  374. package/dist/src/utils/index.js.map +1 -0
  375. package/dist/src/utils/json.d.ts +16 -0
  376. package/dist/src/utils/json.d.ts.map +1 -0
  377. package/dist/src/utils/json.js +43 -0
  378. package/dist/src/utils/json.js.map +1 -0
  379. package/dist/src/utils/logger.d.ts +10 -0
  380. package/dist/src/utils/logger.d.ts.map +1 -0
  381. package/dist/src/utils/logger.js +17 -0
  382. package/dist/src/utils/logger.js.map +1 -0
  383. package/dist/src/utils/retry.d.ts +10 -0
  384. package/dist/src/utils/retry.d.ts.map +1 -0
  385. package/dist/src/utils/retry.js +71 -0
  386. package/dist/src/utils/retry.js.map +1 -0
  387. package/dist/src/utils/session.d.ts +51 -0
  388. package/dist/src/utils/session.d.ts.map +1 -0
  389. package/dist/src/utils/session.js +160 -0
  390. package/dist/src/utils/session.js.map +1 -0
  391. package/dist/src/utils/template.d.ts +155 -0
  392. package/dist/src/utils/template.d.ts.map +1 -0
  393. package/dist/src/utils/template.js +374 -0
  394. package/dist/src/utils/template.js.map +1 -0
  395. package/docs/CONTRIBUTING.md +521 -0
  396. package/docs/README.md +228 -0
  397. package/docs/api/README.md +3258 -0
  398. package/docs/api/overview.md +1134 -0
  399. package/docs/architecture/data-extraction-flow.md +363 -0
  400. package/docs/core/agent/README.md +902 -0
  401. package/docs/core/agent/context-management.md +796 -0
  402. package/docs/core/agent/session-management.md +641 -0
  403. package/docs/core/ai-integration/prompt-composition.md +220 -0
  404. package/docs/core/ai-integration/providers.md +515 -0
  405. package/docs/core/ai-integration/response-processing.md +287 -0
  406. package/docs/core/conversation-flows/data-collection.md +623 -0
  407. package/docs/core/conversation-flows/route-dsl.md +502 -0
  408. package/docs/core/conversation-flows/routes.md +247 -0
  409. package/docs/core/conversation-flows/step-transitions.md +595 -0
  410. package/docs/core/conversation-flows/steps.md +154 -0
  411. package/docs/core/error-handling.md +638 -0
  412. package/docs/core/persistence/adapters.md +255 -0
  413. package/docs/core/persistence/session-storage.md +644 -0
  414. package/docs/core/routing/intelligent-routing.md +466 -0
  415. package/docs/core/tools/tool-definition.md +970 -0
  416. package/docs/core/tools/tool-scoping.md +819 -0
  417. package/docs/guides/advanced-patterns/publishing.md +186 -0
  418. package/docs/guides/error-handling-patterns.md +578 -0
  419. package/docs/guides/getting-started/README.md +696 -0
  420. package/docs/guides/migration/README.md +72 -0
  421. package/docs/guides/migration/flexible-routing-conditions.md +375 -0
  422. package/docs/guides/migration/response-modal-refactor.md +518 -0
  423. package/examples/advanced-patterns/knowledge-based-agent.ts +735 -0
  424. package/examples/advanced-patterns/persistent-onboarding.ts +728 -0
  425. package/examples/advanced-patterns/route-lifecycle-hooks.ts +556 -0
  426. package/examples/advanced-patterns/streaming-responses.ts +578 -0
  427. package/examples/ai-providers/anthropic-integration.ts +388 -0
  428. package/examples/ai-providers/openai-integration.ts +228 -0
  429. package/examples/condition-patterns/function-only-conditions.ts +365 -0
  430. package/examples/condition-patterns/mixed-array-conditions.ts +477 -0
  431. package/examples/condition-patterns/route-skipif-patterns.ts +468 -0
  432. package/examples/condition-patterns/step-skipif-patterns.ts +0 -0
  433. package/examples/condition-patterns/string-only-conditions.ts +296 -0
  434. package/examples/conversation-flows/completion-transitions.ts +318 -0
  435. package/examples/core-concepts/basic-agent.ts +503 -0
  436. package/examples/core-concepts/modern-streaming-api.ts +309 -0
  437. package/examples/core-concepts/schema-driven-extraction.ts +332 -0
  438. package/examples/core-concepts/session-management.ts +494 -0
  439. package/examples/integrations/database-integration.ts +630 -0
  440. package/examples/integrations/healthcare-integration.ts +595 -0
  441. package/examples/integrations/search-integration.ts +530 -0
  442. package/examples/integrations/server-session-management.ts +307 -0
  443. package/examples/persistence/custom-adapter.ts +529 -0
  444. package/examples/persistence/database-persistence.ts +583 -0
  445. package/examples/persistence/memory-sessions.ts +495 -0
  446. package/examples/persistence/prisma-schema.example.prisma +74 -0
  447. package/examples/persistence/redis-persistence.ts +488 -0
  448. package/examples/tools/basic-tools.ts +765 -0
  449. package/examples/tools/data-enrichment-tools.ts +593 -0
  450. package/package.json +125 -0
  451. package/src/adapters/MemoryAdapter.ts +273 -0
  452. package/src/adapters/MongoAdapter.ts +304 -0
  453. package/src/adapters/OpenSearchAdapter.ts +670 -0
  454. package/src/adapters/PostgreSQLAdapter.ts +428 -0
  455. package/src/adapters/PrismaAdapter.ts +553 -0
  456. package/src/adapters/RedisAdapter.ts +377 -0
  457. package/src/adapters/SQLiteAdapter.ts +459 -0
  458. package/src/adapters/index.ts +43 -0
  459. package/src/constants/index.ts +10 -0
  460. package/src/core/Agent.ts +970 -0
  461. package/src/core/Events.ts +164 -0
  462. package/src/core/PersistenceManager.ts +353 -0
  463. package/src/core/PromptComposer.ts +253 -0
  464. package/src/core/ResponseEngine.ts +306 -0
  465. package/src/core/ResponseModal.ts +2050 -0
  466. package/src/core/ResponsePipeline.ts +864 -0
  467. package/src/core/Route.ts +677 -0
  468. package/src/core/RoutingEngine.ts +1396 -0
  469. package/src/core/SessionManager.ts +297 -0
  470. package/src/core/Step.ts +593 -0
  471. package/src/core/ToolManager.ts +1394 -0
  472. package/src/index.ts +155 -0
  473. package/src/providers/AnthropicProvider.ts +560 -0
  474. package/src/providers/GeminiProvider.ts +683 -0
  475. package/src/providers/OpenAIProvider.ts +602 -0
  476. package/src/providers/OpenRouterProvider.ts +613 -0
  477. package/src/providers/index.ts +16 -0
  478. package/src/types/agent.ts +196 -0
  479. package/src/types/ai.ts +158 -0
  480. package/src/types/history.ts +206 -0
  481. package/src/types/index.ts +119 -0
  482. package/src/types/persistence.ts +251 -0
  483. package/src/types/route.ts +272 -0
  484. package/src/types/routing.ts +18 -0
  485. package/src/types/schema.ts +23 -0
  486. package/src/types/session.ts +74 -0
  487. package/src/types/template.ts +104 -0
  488. package/src/types/tool.ts +174 -0
  489. package/src/utils/clone.ts +34 -0
  490. package/src/utils/condition.ts +190 -0
  491. package/src/utils/event.ts +16 -0
  492. package/src/utils/history.ts +306 -0
  493. package/src/utils/id.ts +73 -0
  494. package/src/utils/index.ts +69 -0
  495. package/src/utils/json.ts +46 -0
  496. package/src/utils/logger.ts +19 -0
  497. package/src/utils/retry.ts +97 -0
  498. package/src/utils/session.ts +204 -0
  499. package/src/utils/template.ts +444 -0
@@ -0,0 +1,961 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RoutingEngine = void 0;
4
+ const utils_1 = require("../utils");
5
+ const PromptComposer_1 = require("./PromptComposer");
6
+ const constants_1 = require("../constants");
7
+ const utils_2 = require("../utils");
8
+ class RoutingEngine {
9
+ constructor(options) {
10
+ this.options = options;
11
+ }
12
+ /**
13
+ * Enter a route if not already in it, merging initial data
14
+ * @private
15
+ */
16
+ enterRouteIfNeeded(session, route) {
17
+ if (!session.currentRoute || session.currentRoute.id !== route.id) {
18
+ let updatedSession = (0, utils_1.enterRoute)(session, route.id, route.title);
19
+ if (route.initialData) {
20
+ updatedSession = (0, utils_1.mergeCollected)(updatedSession, route.initialData);
21
+ utils_2.logger.debug(`[RoutingEngine] Merged initial data for route ${route.title}:`, route.initialData);
22
+ }
23
+ utils_2.logger.debug(`[RoutingEngine] Entered route: ${route.title}`);
24
+ return updatedSession;
25
+ }
26
+ return session;
27
+ }
28
+ /**
29
+ * Optimized decision for single-route scenarios
30
+ * Skips route scoring and only does step selection
31
+ * @private
32
+ */
33
+ async decideSingleRouteStep(params) {
34
+ const { route, session, history, agentOptions, provider, context, signal } = params;
35
+ const selectedRoute = route;
36
+ // Enter route if not already in it (this may merge initial data)
37
+ const updatedSession = this.enterRouteIfNeeded(session, route);
38
+ // Check if this single route is complete (use updated session data)
39
+ const completedRoutes = route.isComplete(updatedSession.data || {}) ? [route] : [];
40
+ // Get candidate steps using new condition evaluation
41
+ const templateContext = (0, utils_2.createTemplateContext)({
42
+ context,
43
+ session: updatedSession,
44
+ history,
45
+ data: updatedSession.data
46
+ });
47
+ const currentStep = updatedSession.currentStep
48
+ ? route.getStep(updatedSession.currentStep.id)
49
+ : undefined;
50
+ const candidates = await this.getCandidateStepsWithConditions(route, currentStep, templateContext);
51
+ if (candidates.length === 0) {
52
+ utils_2.logger.warn(`[RoutingEngine] Single-route: No valid steps found`);
53
+ return { selectedRoute, session: updatedSession };
54
+ }
55
+ // If only one candidate, check if it's a completion marker
56
+ if (candidates.length === 1) {
57
+ const candidate = candidates[0];
58
+ if (candidate.isRouteComplete) {
59
+ utils_2.logger.debug(`[RoutingEngine] Single-route: Route complete - all required fields collected or END_ROUTE reached`);
60
+ // Don't return a selectedStep when route is complete - there's no step to enter
61
+ return {
62
+ selectedRoute,
63
+ selectedStep: undefined,
64
+ session: updatedSession,
65
+ isRouteComplete: true,
66
+ completedRoutes,
67
+ };
68
+ }
69
+ else {
70
+ utils_2.logger.debug(`[RoutingEngine] Single-route: Only one valid step: ${candidate.step.id}`);
71
+ return {
72
+ selectedRoute,
73
+ selectedStep: candidate.step,
74
+ session: updatedSession,
75
+ isRouteComplete: false,
76
+ completedRoutes,
77
+ };
78
+ }
79
+ }
80
+ // No candidates means route is likely complete or has no valid next steps
81
+ if (candidates.length === 0) {
82
+ const dataComplete = route.isComplete(updatedSession.data || {});
83
+ utils_2.logger.debug(`[RoutingEngine] Single-route: No valid steps found - ` +
84
+ `(data: ${dataComplete ? 'complete' : 'incomplete'}, marking as ${dataComplete ? 'complete' : 'incomplete'})`);
85
+ return {
86
+ selectedRoute,
87
+ selectedStep: undefined,
88
+ session: updatedSession,
89
+ isRouteComplete: dataComplete,
90
+ completedRoutes,
91
+ };
92
+ }
93
+ // Multiple candidates - use AI to select best step
94
+ const lastUserMessage = (0, utils_2.getLastMessageFromHistory)(history);
95
+ // Collect AI context strings from step conditions
96
+ const stepConditionContext = [];
97
+ for (const candidate of candidates) {
98
+ const whenResult = await candidate.step.evaluateWhen(templateContext);
99
+ stepConditionContext.push(...whenResult.aiContextStrings);
100
+ }
101
+ // Check if any candidate is a completion marker (isRouteComplete = true)
102
+ const hasCompletionOption = candidates.some(c => c.isRouteComplete);
103
+ const stepPrompt = await this.buildStepSelectionPrompt({
104
+ route,
105
+ currentStep,
106
+ candidates,
107
+ data: updatedSession.data || {},
108
+ history,
109
+ lastMessage: lastUserMessage,
110
+ agentOptions,
111
+ context,
112
+ session: updatedSession,
113
+ stepConditionContext,
114
+ includeEndRoute: hasCompletionOption,
115
+ });
116
+ const stepSchema = this.buildStepSelectionSchema(candidates.filter(c => !c.isRouteComplete).map((c) => c.step), hasCompletionOption);
117
+ const stepResult = await provider.generateMessage({
118
+ prompt: stepPrompt,
119
+ history,
120
+ context,
121
+ signal,
122
+ parameters: {
123
+ jsonSchema: stepSchema,
124
+ schemaName: "step_selection",
125
+ },
126
+ });
127
+ const selectedStepId = stepResult.structured?.selectedStepId;
128
+ // Check if AI selected END_ROUTE
129
+ if (selectedStepId === constants_1.END_ROUTE_ID) {
130
+ utils_2.logger.debug(`[RoutingEngine] Single-route: AI selected END_ROUTE - completing route`);
131
+ utils_2.logger.debug(`[RoutingEngine] Single-route: Reasoning: ${stepResult.structured?.reasoning}`);
132
+ return {
133
+ selectedRoute,
134
+ selectedStep: undefined,
135
+ responseDirectives: stepResult.structured?.responseDirectives,
136
+ session: updatedSession,
137
+ isRouteComplete: true,
138
+ completedRoutes,
139
+ };
140
+ }
141
+ const selectedStep = candidates.find((c) => c.step.id === selectedStepId);
142
+ if (selectedStep) {
143
+ utils_2.logger.debug(`[RoutingEngine] Single-route: AI selected step: ${selectedStep.step.id}`);
144
+ utils_2.logger.debug(`[RoutingEngine] Single-route: Reasoning: ${stepResult.structured?.reasoning}`);
145
+ }
146
+ else {
147
+ utils_2.logger.warn(`[RoutingEngine] Single-route: Invalid step ID returned, using first candidate`);
148
+ }
149
+ return {
150
+ selectedRoute,
151
+ selectedStep: selectedStep?.step || candidates[0].step,
152
+ responseDirectives: stepResult.structured?.responseDirectives,
153
+ session: updatedSession,
154
+ completedRoutes,
155
+ };
156
+ }
157
+ /**
158
+ * Recursively traverse step chain to find first non-skipped step or END_ROUTE using new condition evaluation
159
+ * @private
160
+ */
161
+ async findFirstValidStepRecursiveWithConditions(currentStep, templateContext, visited) {
162
+ // Prevent infinite loops
163
+ if (visited.has(currentStep.id)) {
164
+ return { aiContextStrings: [] };
165
+ }
166
+ visited.add(currentStep.id);
167
+ const transitions = currentStep.getTransitions();
168
+ const allAiContextStrings = [];
169
+ for (const transition of transitions) {
170
+ const target = transition;
171
+ // Check for END_ROUTE transition
172
+ if (target && target.id === constants_1.END_ROUTE_ID) {
173
+ // Found END_ROUTE - route is complete
174
+ return {
175
+ isRouteComplete: true,
176
+ aiContextStrings: allAiContextStrings,
177
+ };
178
+ }
179
+ if (!target)
180
+ continue;
181
+ // Evaluate skipIf condition using new system
182
+ const skipResult = await target.evaluateSkipIf(templateContext);
183
+ allAiContextStrings.push(...skipResult.aiContextStrings);
184
+ // If target should NOT be skipped, we found our step
185
+ if (!skipResult.shouldSkip) {
186
+ utils_2.logger.debug(`[RoutingEngine] Found valid step after skipping: ${target.id}`);
187
+ return {
188
+ step: target,
189
+ isRouteComplete: false,
190
+ aiContextStrings: allAiContextStrings,
191
+ };
192
+ }
193
+ // Target should be skipped too - recurse deeper
194
+ utils_2.logger.debug(`[RoutingEngine] Skipping step ${target.id} (skipIf condition met), continuing traversal...`);
195
+ const result = await this.findFirstValidStepRecursiveWithConditions(target, templateContext, visited);
196
+ // Collect AI context from recursive call
197
+ if (result.aiContextStrings) {
198
+ allAiContextStrings.push(...result.aiContextStrings);
199
+ }
200
+ // If we found something (a valid step or END_ROUTE), return it
201
+ if (result.step || result.isRouteComplete) {
202
+ return {
203
+ ...result,
204
+ aiContextStrings: allAiContextStrings,
205
+ };
206
+ }
207
+ }
208
+ // No valid steps or END_ROUTE found in this branch
209
+ return { aiContextStrings: allAiContextStrings };
210
+ }
211
+ /**
212
+ * Identify valid next candidate steps using new condition evaluation system
213
+ * Returns step with isRouteComplete flag if route is complete (all steps skipped + has END_ROUTE transition)
214
+ *
215
+ * NEW: Automatically completes route when all required fields are collected
216
+ */
217
+ async getCandidateStepsWithConditions(route, currentStep, templateContext) {
218
+ const candidates = [];
219
+ const data = templateContext.data || {};
220
+ // Check if all required fields are collected
221
+ const allRequiredFieldsCollected = route.isComplete(data);
222
+ if (!currentStep) {
223
+ // Entering route for the first time
224
+ // If all required fields already collected, route is immediately complete
225
+ if (allRequiredFieldsCollected) {
226
+ utils_2.logger.debug(`[RoutingEngine] Route ${route.title} complete on entry: all required fields already collected`);
227
+ // Return a completion marker - use initial step with completion flag
228
+ candidates.push({
229
+ step: route.initialStep,
230
+ isRouteComplete: true,
231
+ });
232
+ return candidates;
233
+ }
234
+ const initialStep = route.initialStep;
235
+ const skipResult = await initialStep.evaluateSkipIf(templateContext);
236
+ if (skipResult.shouldSkip) {
237
+ // Initial step should be skipped - recursively traverse to find first non-skipped step or END_ROUTE
238
+ const result = await this.findFirstValidStepRecursiveWithConditions(initialStep, templateContext, new Set());
239
+ if (result.isRouteComplete) {
240
+ // All steps are skipped and we reached END_ROUTE
241
+ utils_2.logger.debug(`[RoutingEngine] Route complete on entry: all steps skipped, END_ROUTE reached`);
242
+ candidates.push({
243
+ step: initialStep,
244
+ isRouteComplete: true,
245
+ });
246
+ }
247
+ else if (result.step) {
248
+ // Found a non-skipped step
249
+ candidates.push({
250
+ step: result.step,
251
+ isRouteComplete: result.isRouteComplete || false,
252
+ });
253
+ }
254
+ // If no step found and not complete, fall through to return empty candidates
255
+ }
256
+ else {
257
+ candidates.push({
258
+ step: initialStep,
259
+ isRouteComplete: false,
260
+ });
261
+ }
262
+ return candidates;
263
+ }
264
+ // Check if all required fields are now collected (may have been collected during this step)
265
+ if (allRequiredFieldsCollected) {
266
+ // Required fields are complete - check if we should continue for optional fields
267
+ const transitions = currentStep.getTransitions();
268
+ const optionalFieldCandidates = [];
269
+ for (const transition of transitions) {
270
+ const target = transition;
271
+ // Check for END_ROUTE transition
272
+ if (target && target.id === constants_1.END_ROUTE_ID) {
273
+ continue;
274
+ }
275
+ if (!target)
276
+ continue;
277
+ // Check if this step collects only optional fields
278
+ const collectsOnlyOptional = target.collect && target.collect.length > 0 &&
279
+ target.collect.every(field => route.optionalFields?.includes(field));
280
+ if (collectsOnlyOptional) {
281
+ // This step collects optional fields - it's a candidate
282
+ const skipResult = await target.evaluateSkipIf(templateContext);
283
+ if (!skipResult.shouldSkip) {
284
+ optionalFieldCandidates.push({
285
+ step: target,
286
+ isRouteComplete: false,
287
+ });
288
+ }
289
+ }
290
+ }
291
+ // If we have optional field candidates, include them along with END_ROUTE option
292
+ if (optionalFieldCandidates.length > 0) {
293
+ utils_2.logger.debug(`[RoutingEngine] Required fields complete, but ${optionalFieldCandidates.length} optional field steps available`);
294
+ // Add optional field steps as candidates
295
+ candidates.push(...optionalFieldCandidates);
296
+ // Also add END_ROUTE as a candidate (AI can choose to skip optional fields)
297
+ candidates.push({
298
+ step: currentStep,
299
+ isRouteComplete: true,
300
+ });
301
+ return candidates;
302
+ }
303
+ // No optional fields to collect - route is complete
304
+ utils_2.logger.debug(`[RoutingEngine] Route ${route.title} complete: all required fields collected, no optional fields remain`);
305
+ return [
306
+ {
307
+ step: currentStep,
308
+ isRouteComplete: true,
309
+ },
310
+ ];
311
+ }
312
+ // Required fields not yet complete - continue normal step progression
313
+ const transitions = currentStep.getTransitions();
314
+ let hasEndRoute = false;
315
+ for (const transition of transitions) {
316
+ const target = transition;
317
+ // Check for END_ROUTE transition (no target step)
318
+ if (target && target.id === constants_1.END_ROUTE_ID) {
319
+ hasEndRoute = true;
320
+ continue;
321
+ }
322
+ if (!target)
323
+ continue;
324
+ const skipResult = await target.evaluateSkipIf(templateContext);
325
+ if (skipResult.shouldSkip) {
326
+ utils_2.logger.debug(`[RoutingEngine] Skipping step ${target.id} (skipIf condition met)`);
327
+ // Recursively traverse to find next valid step or END_ROUTE
328
+ const result = await this.findFirstValidStepRecursiveWithConditions(target, templateContext, new Set([currentStep.id]) // Already visited current step
329
+ );
330
+ if (result.isRouteComplete) {
331
+ hasEndRoute = true;
332
+ }
333
+ else if (result.step) {
334
+ // Found a non-skipped step deeper in the chain
335
+ candidates.push({
336
+ step: result.step,
337
+ isRouteComplete: result.isRouteComplete || false,
338
+ });
339
+ }
340
+ continue;
341
+ }
342
+ candidates.push({
343
+ step: target,
344
+ isRouteComplete: hasEndRoute || false,
345
+ });
346
+ }
347
+ // If no valid candidates found
348
+ if (candidates.length === 0) {
349
+ // If current step has END_ROUTE transition, the route is complete
350
+ if (hasEndRoute) {
351
+ utils_2.logger.debug(`[RoutingEngine] Route complete: all steps processed, END_ROUTE reached`);
352
+ // Return current step with completion flag
353
+ return [
354
+ {
355
+ step: currentStep,
356
+ isRouteComplete: true,
357
+ },
358
+ ];
359
+ }
360
+ // Otherwise, stay in current step if it's still valid
361
+ const currentSkipResult = await currentStep.evaluateSkipIf(templateContext);
362
+ if (!currentSkipResult.shouldSkip) {
363
+ candidates.push({
364
+ step: currentStep,
365
+ isRouteComplete: hasEndRoute || false,
366
+ });
367
+ }
368
+ }
369
+ return candidates;
370
+ }
371
+ /**
372
+ * Full routing orchestration: builds prompt and schema, calls AI, selects route/step,
373
+ * and updates the session (including initialData merge when entering a new route).
374
+ *
375
+ * OPTIMIZATION: If there's only 1 route, skips route scoring and only does step selection.
376
+ * CROSS-ROUTE COMPLETION: Evaluates all routes for completion based on collected data.
377
+ */
378
+ async decideRouteAndStep(params) {
379
+ const { routes, session, history, agentOptions, provider, context, signal, } = params;
380
+ if (routes.length === 0) {
381
+ return { session };
382
+ }
383
+ // CROSS-ROUTE COMPLETION EVALUATION: Check all routes for completion
384
+ const completedRoutes = this.evaluateRouteCompletions(routes, session.data || {});
385
+ // Log completed routes
386
+ if (completedRoutes.length > 0) {
387
+ utils_2.logger.debug(`[RoutingEngine] Found ${completedRoutes.length} completed routes: ${completedRoutes.map(r => r.title).join(', ')}`);
388
+ }
389
+ // OPTIMIZATION: Single route - skip route scoring, only do step selection
390
+ if (routes.length === 1) {
391
+ const result = await this.decideSingleRouteStep({
392
+ route: routes[0],
393
+ session,
394
+ history,
395
+ agentOptions,
396
+ provider,
397
+ context,
398
+ signal,
399
+ });
400
+ return {
401
+ ...result,
402
+ completedRoutes,
403
+ };
404
+ }
405
+ const lastUserMessage = (0, utils_2.getLastMessageFromHistory)(history);
406
+ const templateContext = (0, utils_2.createTemplateContext)({
407
+ context,
408
+ session,
409
+ history,
410
+ data: session.data
411
+ });
412
+ // Apply route filtering with new condition evaluation system
413
+ const skipIfResult = await this.filterRoutesBySkipIf(routes, templateContext);
414
+ const whenResult = await this.filterRoutesByWhen(skipIfResult.eligibleRoutes, templateContext);
415
+ // Collect all AI context strings from route conditions
416
+ const routeConditionContext = [...skipIfResult.aiContextStrings, ...whenResult.aiContextStrings];
417
+ // Use filtered routes for further processing
418
+ const eligibleRoutes = whenResult.eligibleRoutes;
419
+ utils_2.logger.debug(`[RoutingEngine] Route filtering: ${routes.length} total → ${skipIfResult.eligibleRoutes.length} after skipIf → ${eligibleRoutes.length} after when`);
420
+ let activeRouteSteps;
421
+ let activeRoute;
422
+ let isRouteComplete = false;
423
+ let updatedSession = session;
424
+ if (session.currentRoute) {
425
+ activeRoute = eligibleRoutes.find((r) => r.id === session.currentRoute?.id);
426
+ if (activeRoute) {
427
+ const currentStep = session.currentStep
428
+ ? activeRoute.getStep(session.currentStep.id)
429
+ : undefined;
430
+ const activeTemplateContext = (0, utils_2.createTemplateContext)({
431
+ ...templateContext,
432
+ session: updatedSession,
433
+ data: updatedSession.data
434
+ });
435
+ const candidates = await this.getCandidateStepsWithConditions(activeRoute, currentStep, activeTemplateContext);
436
+ // Check if route is complete
437
+ // getCandidateStepsWithConditions now automatically handles completion when required fields are collected
438
+ if (candidates.length === 1 && candidates[0].isRouteComplete) {
439
+ isRouteComplete = true;
440
+ utils_2.logger.debug(`[RoutingEngine] Route ${activeRoute.title} is complete - all required fields collected or END_ROUTE reached`);
441
+ // Don't include steps in routing if route is complete
442
+ activeRouteSteps = undefined;
443
+ }
444
+ else if (candidates.length === 0) {
445
+ // No candidates - check if data is complete
446
+ const dataComplete = activeRoute.isComplete(updatedSession.data || {});
447
+ isRouteComplete = dataComplete;
448
+ utils_2.logger.debug(`[RoutingEngine] Route ${activeRoute.title} has no valid steps - ` +
449
+ `marking as ${isRouteComplete ? 'complete' : 'incomplete'}`);
450
+ activeRouteSteps = undefined;
451
+ }
452
+ else {
453
+ // Multiple candidates or single non-complete candidate
454
+ activeRouteSteps = candidates.map((c) => c.step);
455
+ utils_2.logger.debug(`[RoutingEngine] Found ${activeRouteSteps.length} candidate steps for active route`);
456
+ }
457
+ }
458
+ }
459
+ const routingSchema = this.buildDynamicRoutingSchema(eligibleRoutes, undefined, activeRouteSteps);
460
+ const routingPrompt = await this.buildRoutingPrompt({
461
+ history,
462
+ routes: eligibleRoutes,
463
+ lastMessage: lastUserMessage,
464
+ agentOptions,
465
+ session,
466
+ activeRouteSteps,
467
+ context,
468
+ routeConditionContext, // Pass AI context strings from route conditions
469
+ });
470
+ const routingResult = await provider.generateMessage({
471
+ prompt: routingPrompt,
472
+ history,
473
+ context,
474
+ signal,
475
+ parameters: {
476
+ jsonSchema: routingSchema,
477
+ schemaName: "routing_output",
478
+ },
479
+ });
480
+ let selectedRoute;
481
+ let selectedStep;
482
+ let responseDirectives;
483
+ if (routingResult.structured?.routes) {
484
+ // Use cross-route completion evaluation to select optimal route
485
+ const optimalRoute = this.selectOptimalRoute(eligibleRoutes, updatedSession.data || {}, routingResult.structured.routes);
486
+ // If no optimal route found, check why
487
+ if (!optimalRoute) {
488
+ if (eligibleRoutes.length === 0) {
489
+ // No routes passed filtering
490
+ utils_2.logger.debug(`[RoutingEngine] No eligible routes available - all routes filtered out`);
491
+ selectedRoute = undefined;
492
+ }
493
+ else {
494
+ // Routes exist but selectOptimalRoute returned undefined
495
+ // This means all routes are 100% complete
496
+ utils_2.logger.debug(`[RoutingEngine] No optimal route found - all ${eligibleRoutes.length} eligible routes are complete`);
497
+ selectedRoute = undefined;
498
+ }
499
+ }
500
+ else {
501
+ selectedRoute = optimalRoute;
502
+ }
503
+ responseDirectives = routingResult.structured.responseDirectives;
504
+ if (selectedRoute === activeRoute &&
505
+ routingResult.structured.selectedStepId &&
506
+ activeRoute) {
507
+ selectedStep = activeRoute.getStep(routingResult.structured.selectedStepId);
508
+ if (selectedStep) {
509
+ utils_2.logger.debug(`[RoutingEngine] AI selected step: ${selectedStep.id} in active route`);
510
+ utils_2.logger.debug(`[RoutingEngine] Step reasoning: ${routingResult.structured.stepReasoning}`);
511
+ }
512
+ }
513
+ if (selectedRoute) {
514
+ utils_2.logger.debug(`[RoutingEngine] Selected route: ${selectedRoute.title}`);
515
+ updatedSession = this.enterRouteIfNeeded(updatedSession, selectedRoute);
516
+ }
517
+ }
518
+ return {
519
+ selectedRoute,
520
+ selectedStep,
521
+ responseDirectives,
522
+ session: updatedSession,
523
+ isRouteComplete,
524
+ completedRoutes,
525
+ };
526
+ }
527
+ /**
528
+ * Filter routes based on skipIf conditions
529
+ * @param routes - All available routes
530
+ * @param templateContext - Context for condition evaluation
531
+ * @returns Object with eligible routes and collected AI context strings
532
+ */
533
+ async filterRoutesBySkipIf(routes, templateContext) {
534
+ const eligibleRoutes = [];
535
+ const aiContextStrings = [];
536
+ for (const route of routes) {
537
+ const skipResult = await route.evaluateSkipIf(templateContext);
538
+ // Collect AI context strings from skipIf conditions
539
+ aiContextStrings.push(...skipResult.aiContextStrings);
540
+ // If route should not be skipped, it's eligible
541
+ if (!skipResult.programmaticResult) {
542
+ eligibleRoutes.push(route);
543
+ }
544
+ else {
545
+ utils_2.logger.debug(`[RoutingEngine] Skipping route ${route.title} (skipIf condition met)`);
546
+ }
547
+ }
548
+ return { eligibleRoutes, aiContextStrings };
549
+ }
550
+ /**
551
+ * Filter routes based on when conditions
552
+ * @param routes - Routes that passed skipIf filtering
553
+ * @param templateContext - Context for condition evaluation
554
+ * @returns Object with eligible routes and collected AI context strings
555
+ */
556
+ async filterRoutesByWhen(routes, templateContext) {
557
+ const eligibleRoutes = [];
558
+ const aiContextStrings = [];
559
+ for (const route of routes) {
560
+ const whenResult = await route.evaluateWhen(templateContext);
561
+ // Collect AI context strings from when conditions
562
+ aiContextStrings.push(...whenResult.aiContextStrings);
563
+ // If route has no programmatic conditions or they evaluate to true, it's eligible
564
+ if (!whenResult.hasProgrammaticConditions || whenResult.programmaticResult) {
565
+ eligibleRoutes.push(route);
566
+ }
567
+ else {
568
+ utils_2.logger.debug(`[RoutingEngine] Route ${route.title} not eligible (when condition not met)`);
569
+ }
570
+ }
571
+ return { eligibleRoutes, aiContextStrings };
572
+ }
573
+ /**
574
+ * Evaluate all routes for completion based on collected data
575
+ * @param routes - All available routes
576
+ * @param data - Currently collected agent-level data
577
+ * @returns Array of routes that are complete
578
+ */
579
+ evaluateRouteCompletions(routes, data) {
580
+ return routes.filter(route => route.isComplete(data));
581
+ }
582
+ /**
583
+ * Get completion status for all routes
584
+ * @param routes - All available routes
585
+ * @param data - Currently collected agent-level data
586
+ * @returns Map of route ID to completion progress (0-1)
587
+ */
588
+ getRouteCompletionStatus(routes, data) {
589
+ const completionStatus = new Map();
590
+ for (const route of routes) {
591
+ const progress = route.getCompletionProgress(data);
592
+ completionStatus.set(route.id, progress);
593
+ }
594
+ return completionStatus;
595
+ }
596
+ /**
597
+ * Find the best route to continue based on completion status and user intent
598
+ * Prioritizes routes that are partially complete but not finished
599
+ * IMPORTANT: Completed routes are excluded to prevent re-entering finished tasks
600
+ * @param routes - All available routes
601
+ * @param data - Currently collected agent-level data
602
+ * @param routeScores - AI-generated route scores from routing decision
603
+ * @returns Route that should be prioritized for continuation
604
+ */
605
+ selectOptimalRoute(routes, data, routeScores) {
606
+ const completionStatus = this.getRouteCompletionStatus(routes, data);
607
+ // Create weighted scores combining AI intent scores with completion progress
608
+ const weightedScores = [];
609
+ for (const route of routes) {
610
+ const aiScore = routeScores[route.id] || 0;
611
+ const completionProgress = completionStatus.get(route.id) || 0;
612
+ // ALWAYS skip fully completed routes to prevent re-entering finished tasks
613
+ // Users should not be forced back into completed routes
614
+ if (completionProgress >= 1.0) {
615
+ utils_2.logger.debug(`[RoutingEngine] Excluding completed route: ${route.title} (100% complete)`);
616
+ continue;
617
+ }
618
+ // Boost partially complete routes that match user intent
619
+ let weightedScore = aiScore;
620
+ if (completionProgress > 0 && completionProgress < 1.0) {
621
+ // Boost score for partially complete routes
622
+ weightedScore += (completionProgress * 20); // Up to 20 point boost
623
+ }
624
+ weightedScores.push({ route, score: weightedScore });
625
+ }
626
+ // Sort by weighted score and return the best option
627
+ weightedScores.sort((a, b) => b.score - a.score);
628
+ if (weightedScores.length > 0) {
629
+ utils_2.logger.debug(`[RoutingEngine] Selected optimal route: ${weightedScores[0].route.title} ` +
630
+ `(AI: ${routeScores[weightedScores[0].route.id]}, ` +
631
+ `Completion: ${(completionStatus.get(weightedScores[0].route.id) || 0) * 100}%, ` +
632
+ `Weighted: ${weightedScores[0].score})`);
633
+ return weightedScores[0].route;
634
+ }
635
+ return undefined;
636
+ }
637
+ /**
638
+ * Build prompt for step selection within a single route
639
+ * @private
640
+ */
641
+ async buildStepSelectionPrompt(params) {
642
+ const { route, currentStep, candidates, data, history, lastMessage, agentOptions, context, session, stepConditionContext, includeEndRoute = false, } = params;
643
+ const templateContext = (0, utils_2.createTemplateContext)({ context, session, history });
644
+ const pc = new PromptComposer_1.PromptComposer(templateContext);
645
+ // Add agent metadata
646
+ if (agentOptions) {
647
+ await pc.addAgentMeta(agentOptions);
648
+ }
649
+ // Add route context
650
+ await pc.addInstruction(`Active Route: ${route.title}\nDescription: ${route.description || "N/A"}`);
651
+ // Add current step context
652
+ if (currentStep) {
653
+ await pc.addInstruction(`Current Step: ${currentStep.id}\nDescription: ${currentStep.description || "N/A"}`);
654
+ }
655
+ else {
656
+ await pc.addInstruction("Current Step: None (entering route)");
657
+ }
658
+ // Add collected data context
659
+ if (Object.keys(data).length > 0) {
660
+ await pc.addInstruction(`Collected Data So Far:\n${JSON.stringify(data, null, 2)}`);
661
+ }
662
+ else {
663
+ await pc.addInstruction("Collected Data: None yet");
664
+ }
665
+ // Add conversation history
666
+ await pc.addInteractionHistory(history);
667
+ await pc.addLastMessage(lastMessage);
668
+ // Add candidate steps with condition context
669
+ const stepDescriptions = [];
670
+ for (const candidate of candidates) {
671
+ const idx = candidates.indexOf(candidate);
672
+ const parts = [
673
+ `${idx + 1}. Step ID: ${candidate.step.id}`,
674
+ ` Description: ${candidate.step.description || "N/A"}`,
675
+ ];
676
+ // Add when condition context
677
+ if (candidate.step.when) {
678
+ const whenResult = await candidate.step.evaluateWhen(templateContext);
679
+ if (whenResult.aiContextStrings.length > 0) {
680
+ parts.push(` When conditions: ${whenResult.aiContextStrings.join(", ")}`);
681
+ }
682
+ else if (typeof candidate.step.when === 'string') {
683
+ parts.push(` When this step should be completed: ${candidate.step.when}`);
684
+ }
685
+ }
686
+ if (candidate.step.requires && candidate.step.requires.length > 0) {
687
+ parts.push(` Required Data: ${candidate.step.requires.join(", ")}`);
688
+ }
689
+ if (candidate.step.collect && candidate.step.collect.length > 0) {
690
+ parts.push(` Collects: ${candidate.step.collect.join(", ")}`);
691
+ }
692
+ stepDescriptions.push(parts.join("\n"));
693
+ }
694
+ await pc.addInstruction(`Available Steps to Transition To:\n${stepDescriptions.join("\n\n")}`);
695
+ // Add step condition context if available
696
+ if (stepConditionContext && stepConditionContext.length > 0) {
697
+ await pc.addInstruction([
698
+ "",
699
+ "Additional step context from conditions:",
700
+ ...stepConditionContext.map(ctx => `- ${ctx}`),
701
+ "",
702
+ "Consider this context when selecting the most appropriate step.",
703
+ ].join("\n"));
704
+ }
705
+ // Add decision prompt
706
+ const decisionRules = [
707
+ "Task: Decide which step to transition to based on:",
708
+ "1. The user's current message and intent",
709
+ "2. The conversation history and context",
710
+ "3. The collected data we already have",
711
+ "4. The conditions and requirements of each step",
712
+ "5. The logical flow of the conversation",
713
+ "",
714
+ "Rules:",
715
+ "- If a step has a condition, evaluate whether it's met based on context",
716
+ "- If a step requires data we don't have, consider if we should collect it now",
717
+ "- Choose the step that makes the most sense for moving the conversation forward",
718
+ "- Steps with skipIf conditions that are met have already been filtered out",
719
+ ];
720
+ if (includeEndRoute) {
721
+ decisionRules.push("", `- You can select '${constants_1.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");
722
+ }
723
+ decisionRules.push("", "Return ONLY JSON matching the provided schema.");
724
+ await pc.addInstruction(decisionRules.join("\n"));
725
+ return pc.build();
726
+ }
727
+ /**
728
+ * Build schema for step selection
729
+ * @private
730
+ */
731
+ buildStepSelectionSchema(validSteps, includeEndRoute = false) {
732
+ const stepIds = validSteps.map((s) => s.id);
733
+ // Add END_ROUTE as an option if requested (when required fields are complete)
734
+ if (includeEndRoute) {
735
+ stepIds.push(constants_1.END_ROUTE_ID);
736
+ }
737
+ return {
738
+ description: "Step transition decision based on conversation context and collected data",
739
+ type: "object",
740
+ properties: {
741
+ reasoning: {
742
+ type: "string",
743
+ nullable: false,
744
+ description: "Brief explanation of why this step was selected",
745
+ },
746
+ selectedStepId: {
747
+ type: "string",
748
+ nullable: false,
749
+ description: includeEndRoute
750
+ ? `The ID of the selected step to transition to, or '${constants_1.END_ROUTE_ID}' to complete the route`
751
+ : "The ID of the selected step to transition to",
752
+ enum: stepIds,
753
+ },
754
+ responseDirectives: {
755
+ type: "array",
756
+ items: { type: "string" },
757
+ description: "Optional bullet points the response should address (concise)",
758
+ },
759
+ },
760
+ required: ["reasoning", "selectedStepId"],
761
+ additionalProperties: false,
762
+ };
763
+ }
764
+ buildDynamicRoutingSchema(routes, extrasSchema, activeRouteSteps) {
765
+ const routeIds = routes.map((r) => r.id);
766
+ const routeProperties = {};
767
+ for (const id of routeIds) {
768
+ routeProperties[id] = {
769
+ type: "number",
770
+ nullable: false,
771
+ description: `Score for route ${id} based on direct evidence, context and semantic fit (0-100)`,
772
+ minimum: 0,
773
+ maximum: 100,
774
+ };
775
+ }
776
+ const base = {
777
+ description: "Full intent analysis: score ALL available routes (0-100) using evidence and context",
778
+ type: "object",
779
+ properties: {
780
+ context: {
781
+ type: "string",
782
+ nullable: false,
783
+ description: "Brief summary of the user's intent/context",
784
+ },
785
+ routes: {
786
+ type: "object",
787
+ properties: routeProperties,
788
+ required: routeIds,
789
+ nullable: false,
790
+ description: "Mapping of routeId to score (0-100)",
791
+ },
792
+ responseDirectives: {
793
+ type: "array",
794
+ items: { type: "string" },
795
+ description: "Optional bullet points the response should address (concise)",
796
+ },
797
+ },
798
+ required: ["context", "routes"],
799
+ additionalProperties: false,
800
+ };
801
+ // Add step selection fields if there's an active route with steps
802
+ if (activeRouteSteps && activeRouteSteps.length > 0) {
803
+ base.properties = base.properties || {};
804
+ base.properties.selectedStepId = {
805
+ type: "string",
806
+ nullable: false,
807
+ description: "The step ID to transition to within the active route (required if continuing in current route)",
808
+ enum: activeRouteSteps.map((s) => s.id),
809
+ };
810
+ base.properties.stepReasoning = {
811
+ type: "string",
812
+ nullable: false,
813
+ description: "Brief explanation of why this step was selected",
814
+ };
815
+ base.required = [
816
+ ...(base.required || []),
817
+ "selectedStepId",
818
+ "stepReasoning",
819
+ ];
820
+ }
821
+ if (extrasSchema) {
822
+ base.properties = base.properties || {};
823
+ base.properties.extractions = extrasSchema;
824
+ }
825
+ return base;
826
+ }
827
+ async buildRoutingPrompt(params) {
828
+ const { history, routes, lastMessage, agentOptions, session, activeRouteSteps, context, routeConditionContext, } = params;
829
+ const templateContext = (0, utils_2.createTemplateContext)({ context, session, history });
830
+ const pc = new PromptComposer_1.PromptComposer(templateContext);
831
+ if (agentOptions) {
832
+ await pc.addAgentMeta(agentOptions);
833
+ }
834
+ await pc.addInstruction("Task: Intent analysis and route scoring (0-100). Score ALL listed routes.");
835
+ // Add session context if available
836
+ if (session?.currentRoute) {
837
+ const sessionInfo = [
838
+ "Current conversation context:",
839
+ `- Active route: ${session.currentRoute.title} (${session.currentRoute.id})`,
840
+ ];
841
+ if (session.currentStep) {
842
+ sessionInfo.push(`- Current step: ${session.currentStep.id}`);
843
+ if (session.currentStep.description) {
844
+ sessionInfo.push(` "${session.currentStep.description}"`);
845
+ }
846
+ }
847
+ if (session.data && Object.keys(session.data).length > 0) {
848
+ sessionInfo.push(`- Collected data: ${JSON.stringify(session.data)}`);
849
+ }
850
+ sessionInfo.push("Note: User is mid-conversation. They may want to continue current route or switch to a new one based on their intent.");
851
+ await pc.addInstruction(sessionInfo.join("\n"));
852
+ // Add cross-route completion status
853
+ const completionStatus = this.getRouteCompletionStatus(routes, session.data || {});
854
+ const completedRoutes = this.evaluateRouteCompletions(routes, session.data || {});
855
+ if (completionStatus.size > 0) {
856
+ const statusInfo = [
857
+ "",
858
+ "Route completion status based on collected data:",
859
+ ];
860
+ for (const route of routes) {
861
+ const progress = completionStatus.get(route.id) || 0;
862
+ const isComplete = completedRoutes.includes(route);
863
+ const progressPercent = Math.round(progress * 100);
864
+ statusInfo.push(`- ${route.title}: ${progressPercent}% complete${isComplete ? ' ✓ COMPLETE' : ''}`);
865
+ if (!isComplete && route.requiredFields) {
866
+ const missingFields = route.getMissingRequiredFields(session.data || {});
867
+ if (missingFields.length > 0) {
868
+ statusInfo.push(` Missing: ${missingFields.join(', ')}`);
869
+ }
870
+ }
871
+ }
872
+ statusInfo.push("", "Consider route completion status when scoring. Partially complete routes may be good candidates for continuation.");
873
+ await pc.addInstruction(statusInfo.join("\n"));
874
+ }
875
+ // Add available steps for the active route
876
+ if (activeRouteSteps && activeRouteSteps.length > 0) {
877
+ const stepInfo = [
878
+ "",
879
+ "Available steps in active route (choose one to transition to):",
880
+ ];
881
+ const activeStepConditionContext = [];
882
+ for (const step of activeRouteSteps) {
883
+ const idx = activeRouteSteps.indexOf(step);
884
+ stepInfo.push(`${idx + 1}. Step: ${step.id}`);
885
+ if (step.description) {
886
+ stepInfo.push(` Description: ${step.description}`);
887
+ }
888
+ // Collect AI context from step conditions
889
+ if (step.when) {
890
+ const whenResult = await step.evaluateWhen(templateContext);
891
+ if (whenResult.aiContextStrings.length > 0) {
892
+ stepInfo.push(` When conditions: ${whenResult.aiContextStrings.join(", ")}`);
893
+ activeStepConditionContext.push(...whenResult.aiContextStrings);
894
+ }
895
+ else if (typeof step.when === 'string') {
896
+ stepInfo.push(` When this step should be completed: ${step.when}`);
897
+ }
898
+ }
899
+ if (step.requires && step.requires.length > 0) {
900
+ stepInfo.push(` Required data: ${step.requires.join(", ")}`);
901
+ }
902
+ if (step.collect && step.collect.length > 0) {
903
+ stepInfo.push(` Will collect: ${step.collect.join(", ")}`);
904
+ }
905
+ }
906
+ stepInfo.push("");
907
+ stepInfo.push("IMPORTANT: You MUST select a step to transition to. Evaluate which step makes the most sense based on:");
908
+ stepInfo.push("- The conversation flow and what's been collected");
909
+ stepInfo.push("- What data is still needed vs already present");
910
+ stepInfo.push("- The logical next step in the conversation");
911
+ stepInfo.push("- Whether conditions for steps are met");
912
+ await pc.addInstruction(stepInfo.join("\n"));
913
+ // Add active step condition context if available
914
+ if (activeStepConditionContext.length > 0) {
915
+ await pc.addInstruction([
916
+ "",
917
+ "Additional context from step conditions:",
918
+ ...activeStepConditionContext.map(ctx => `- ${ctx}`),
919
+ "",
920
+ "Use this context to inform your step selection decision.",
921
+ ].join("\n"));
922
+ }
923
+ }
924
+ }
925
+ await pc.addInteractionHistory(history);
926
+ await pc.addLastMessage(lastMessage);
927
+ await pc.addRoutingOverview(routes);
928
+ // Add route condition context if available
929
+ if (routeConditionContext && routeConditionContext.length > 0) {
930
+ await pc.addInstruction([
931
+ "",
932
+ "Additional routing context from route conditions:",
933
+ ...routeConditionContext.map(ctx => `- ${ctx}`),
934
+ "",
935
+ "Consider this context when scoring routes for relevance.",
936
+ ].join("\n"));
937
+ }
938
+ await pc.addInstruction([
939
+ "Scoring rules:",
940
+ "- 90-100: explicit keywords + clear intent",
941
+ "- 70-89: strong contextual evidence + relevant keywords",
942
+ "- 50-69: moderate relevance",
943
+ "- 30-49: weak connection or ambiguous",
944
+ "- 0-29: minimal/none",
945
+ "Return ONLY JSON matching the provided schema. Include scores for ALL routes.",
946
+ ].join("\n"));
947
+ return pc.build();
948
+ }
949
+ decideRouteFromScores(output) {
950
+ // Optionally limit candidates and apply switching threshold
951
+ const entries = Object.entries(output.routes).sort((a, b) => b[1] - a[1]);
952
+ const limited = this.options?.maxCandidates
953
+ ? entries.slice(0, this.options.maxCandidates)
954
+ : entries;
955
+ const [topId, topScore] = limited[0] || ["", 0];
956
+ // switchThreshold is enforced by caller when a current route exists
957
+ return { routeId: topId, maxScore: topScore };
958
+ }
959
+ }
960
+ exports.RoutingEngine = RoutingEngine;
961
+ //# sourceMappingURL=RoutingEngine.js.map