@falai/agent 0.9.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (626) hide show
  1. package/README.md +262 -38
  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 +6 -1
  33. package/dist/cjs/core/Agent.d.ts.map +1 -0
  34. package/dist/cjs/{src/core → core}/Agent.js +42 -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 +842 -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 +201 -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 +202 -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 +686 -66
  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 +11 -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 +6 -1
  135. package/dist/core/Agent.d.ts.map +1 -0
  136. package/dist/{src/core → core}/Agent.js +43 -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 +837 -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 +197 -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 +198 -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 +686 -66
  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 +11 -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/api/README.md +221 -12
  259. package/docs/api/overview.md +202 -3
  260. package/docs/architecture/data-extraction-flow.md +363 -0
  261. package/docs/architecture/multi-step-execution.md +243 -0
  262. package/docs/core/agent/README.md +120 -5
  263. package/docs/core/agent/session-management.md +1 -1
  264. package/docs/core/ai-integration/prompt-composition.md +135 -0
  265. package/docs/core/ai-integration/response-processing.md +146 -0
  266. package/docs/core/conversation-flows/data-collection.md +143 -0
  267. package/docs/core/conversation-flows/routes.md +2 -2
  268. package/docs/core/conversation-flows/step-transitions.md +132 -0
  269. package/docs/core/conversation-flows/steps.md +112 -0
  270. package/docs/core/error-handling.md +193 -0
  271. package/docs/core/routing/intelligent-routing.md +118 -0
  272. package/docs/guides/getting-started/README.md +284 -3
  273. package/docs/guides/migration/README.md +23 -0
  274. package/docs/guides/migration/flexible-routing-conditions.md +375 -0
  275. package/docs/guides/migration/multi-step-execution.md +303 -0
  276. package/examples/advanced-patterns/knowledge-based-agent.ts +101 -24
  277. package/examples/advanced-patterns/persistent-onboarding.ts +40 -5
  278. package/examples/advanced-patterns/route-lifecycle-hooks.ts +82 -12
  279. package/examples/advanced-patterns/streaming-responses.ts +2 -2
  280. package/examples/ai-providers/anthropic-integration.ts +4 -4
  281. package/examples/ai-providers/openai-integration.ts +1 -1
  282. package/examples/condition-patterns/function-only-conditions.ts +365 -0
  283. package/examples/condition-patterns/mixed-array-conditions.ts +477 -0
  284. package/examples/condition-patterns/route-skipif-patterns.ts +468 -0
  285. package/examples/condition-patterns/step-skipif-patterns.ts +0 -0
  286. package/examples/condition-patterns/string-only-conditions.ts +296 -0
  287. package/examples/conversation-flows/completion-transitions.ts +48 -7
  288. package/examples/core-concepts/basic-agent.ts +54 -33
  289. package/examples/core-concepts/schema-driven-extraction.ts +33 -9
  290. package/examples/core-concepts/session-management.ts +51 -16
  291. package/examples/integrations/database-integration.ts +6 -6
  292. package/examples/integrations/healthcare-integration.ts +10 -10
  293. package/examples/integrations/search-integration.ts +8 -8
  294. package/examples/integrations/server-session-management.ts +8 -8
  295. package/examples/persistence/database-persistence.ts +15 -15
  296. package/examples/persistence/memory-sessions.ts +3 -3
  297. package/examples/persistence/redis-persistence.ts +7 -9
  298. package/examples/tools/data-enrichment-tools.ts +4 -4
  299. package/package.json +6 -4
  300. package/src/adapters/PrismaAdapter.ts +3 -2
  301. package/src/adapters/RedisAdapter.ts +3 -3
  302. package/src/core/Agent.ts +54 -2
  303. package/src/core/BatchExecutor.ts +1156 -0
  304. package/src/core/BatchPromptBuilder.ts +275 -0
  305. package/src/core/PromptComposer.ts +53 -16
  306. package/src/core/ResponseEngine.ts +143 -4
  307. package/src/core/ResponseModal.ts +888 -66
  308. package/src/core/ResponsePipeline.ts +17 -9
  309. package/src/core/Route.ts +223 -22
  310. package/src/core/RoutingEngine.ts +426 -83
  311. package/src/core/Step.ts +144 -16
  312. package/src/index.ts +19 -0
  313. package/src/providers/AnthropicProvider.ts +17 -17
  314. package/src/providers/GeminiProvider.ts +129 -60
  315. package/src/providers/OpenAIProvider.ts +18 -18
  316. package/src/providers/OpenRouterProvider.ts +18 -18
  317. package/src/types/agent.ts +11 -3
  318. package/src/types/index.ts +12 -1
  319. package/src/types/route.ts +131 -12
  320. package/src/types/template.ts +70 -2
  321. package/src/utils/condition.ts +190 -0
  322. package/src/utils/index.ts +12 -0
  323. package/src/utils/json.ts +46 -0
  324. package/src/utils/retry.ts +5 -4
  325. package/src/utils/template.ts +109 -0
  326. package/dist/cjs/src/adapters/MemoryAdapter.d.ts.map +0 -1
  327. package/dist/cjs/src/adapters/MemoryAdapter.js.map +0 -1
  328. package/dist/cjs/src/adapters/MongoAdapter.d.ts.map +0 -1
  329. package/dist/cjs/src/adapters/MongoAdapter.js.map +0 -1
  330. package/dist/cjs/src/adapters/OpenSearchAdapter.d.ts.map +0 -1
  331. package/dist/cjs/src/adapters/OpenSearchAdapter.js.map +0 -1
  332. package/dist/cjs/src/adapters/PostgreSQLAdapter.d.ts.map +0 -1
  333. package/dist/cjs/src/adapters/PostgreSQLAdapter.js.map +0 -1
  334. package/dist/cjs/src/adapters/PrismaAdapter.d.ts.map +0 -1
  335. package/dist/cjs/src/adapters/PrismaAdapter.js.map +0 -1
  336. package/dist/cjs/src/adapters/RedisAdapter.d.ts.map +0 -1
  337. package/dist/cjs/src/adapters/RedisAdapter.js.map +0 -1
  338. package/dist/cjs/src/adapters/SQLiteAdapter.d.ts.map +0 -1
  339. package/dist/cjs/src/adapters/SQLiteAdapter.js.map +0 -1
  340. package/dist/cjs/src/adapters/index.d.ts.map +0 -1
  341. package/dist/cjs/src/adapters/index.js.map +0 -1
  342. package/dist/cjs/src/constants/index.d.ts.map +0 -1
  343. package/dist/cjs/src/constants/index.js.map +0 -1
  344. package/dist/cjs/src/core/Agent.d.ts.map +0 -1
  345. package/dist/cjs/src/core/Agent.js.map +0 -1
  346. package/dist/cjs/src/core/Events.d.ts.map +0 -1
  347. package/dist/cjs/src/core/Events.js.map +0 -1
  348. package/dist/cjs/src/core/PersistenceManager.d.ts.map +0 -1
  349. package/dist/cjs/src/core/PersistenceManager.js.map +0 -1
  350. package/dist/cjs/src/core/PromptComposer.d.ts.map +0 -1
  351. package/dist/cjs/src/core/PromptComposer.js.map +0 -1
  352. package/dist/cjs/src/core/ResponseEngine.d.ts.map +0 -1
  353. package/dist/cjs/src/core/ResponseEngine.js +0 -84
  354. package/dist/cjs/src/core/ResponseEngine.js.map +0 -1
  355. package/dist/cjs/src/core/ResponseModal.d.ts.map +0 -1
  356. package/dist/cjs/src/core/ResponseModal.js.map +0 -1
  357. package/dist/cjs/src/core/ResponsePipeline.d.ts.map +0 -1
  358. package/dist/cjs/src/core/ResponsePipeline.js.map +0 -1
  359. package/dist/cjs/src/core/Route.d.ts.map +0 -1
  360. package/dist/cjs/src/core/Route.js.map +0 -1
  361. package/dist/cjs/src/core/RoutingEngine.d.ts.map +0 -1
  362. package/dist/cjs/src/core/RoutingEngine.js.map +0 -1
  363. package/dist/cjs/src/core/SessionManager.d.ts.map +0 -1
  364. package/dist/cjs/src/core/SessionManager.js.map +0 -1
  365. package/dist/cjs/src/core/Step.d.ts.map +0 -1
  366. package/dist/cjs/src/core/Step.js.map +0 -1
  367. package/dist/cjs/src/core/ToolManager.d.ts.map +0 -1
  368. package/dist/cjs/src/core/ToolManager.js.map +0 -1
  369. package/dist/cjs/src/index.d.ts.map +0 -1
  370. package/dist/cjs/src/index.js.map +0 -1
  371. package/dist/cjs/src/providers/AnthropicProvider.d.ts.map +0 -1
  372. package/dist/cjs/src/providers/AnthropicProvider.js.map +0 -1
  373. package/dist/cjs/src/providers/GeminiProvider.d.ts.map +0 -1
  374. package/dist/cjs/src/providers/GeminiProvider.js.map +0 -1
  375. package/dist/cjs/src/providers/OpenAIProvider.d.ts.map +0 -1
  376. package/dist/cjs/src/providers/OpenAIProvider.js.map +0 -1
  377. package/dist/cjs/src/providers/OpenRouterProvider.d.ts.map +0 -1
  378. package/dist/cjs/src/providers/OpenRouterProvider.js.map +0 -1
  379. package/dist/cjs/src/providers/index.d.ts.map +0 -1
  380. package/dist/cjs/src/providers/index.js.map +0 -1
  381. package/dist/cjs/src/types/agent.d.ts.map +0 -1
  382. package/dist/cjs/src/types/agent.js.map +0 -1
  383. package/dist/cjs/src/types/ai.d.ts.map +0 -1
  384. package/dist/cjs/src/types/ai.js.map +0 -1
  385. package/dist/cjs/src/types/history.d.ts.map +0 -1
  386. package/dist/cjs/src/types/history.js.map +0 -1
  387. package/dist/cjs/src/types/index.d.ts.map +0 -1
  388. package/dist/cjs/src/types/index.js.map +0 -1
  389. package/dist/cjs/src/types/persistence.d.ts.map +0 -1
  390. package/dist/cjs/src/types/persistence.js.map +0 -1
  391. package/dist/cjs/src/types/route.d.ts.map +0 -1
  392. package/dist/cjs/src/types/routing.d.ts.map +0 -1
  393. package/dist/cjs/src/types/schema.d.ts.map +0 -1
  394. package/dist/cjs/src/types/session.d.ts.map +0 -1
  395. package/dist/cjs/src/types/session.js.map +0 -1
  396. package/dist/cjs/src/types/template.d.ts +0 -30
  397. package/dist/cjs/src/types/template.d.ts.map +0 -1
  398. package/dist/cjs/src/types/tool.d.ts.map +0 -1
  399. package/dist/cjs/src/types/tool.js.map +0 -1
  400. package/dist/cjs/src/utils/clone.d.ts.map +0 -1
  401. package/dist/cjs/src/utils/clone.js.map +0 -1
  402. package/dist/cjs/src/utils/event.d.ts.map +0 -1
  403. package/dist/cjs/src/utils/event.js.map +0 -1
  404. package/dist/cjs/src/utils/history.d.ts.map +0 -1
  405. package/dist/cjs/src/utils/history.js.map +0 -1
  406. package/dist/cjs/src/utils/id.d.ts.map +0 -1
  407. package/dist/cjs/src/utils/id.js.map +0 -1
  408. package/dist/cjs/src/utils/index.d.ts.map +0 -1
  409. package/dist/cjs/src/utils/index.js.map +0 -1
  410. package/dist/cjs/src/utils/logger.d.ts.map +0 -1
  411. package/dist/cjs/src/utils/logger.js.map +0 -1
  412. package/dist/cjs/src/utils/retry.d.ts.map +0 -1
  413. package/dist/cjs/src/utils/retry.js.map +0 -1
  414. package/dist/cjs/src/utils/session.d.ts.map +0 -1
  415. package/dist/cjs/src/utils/session.js.map +0 -1
  416. package/dist/cjs/src/utils/template.d.ts.map +0 -1
  417. package/dist/cjs/src/utils/template.js.map +0 -1
  418. package/dist/src/adapters/MemoryAdapter.js.map +0 -1
  419. package/dist/src/adapters/MongoAdapter.js.map +0 -1
  420. package/dist/src/adapters/OpenSearchAdapter.js.map +0 -1
  421. package/dist/src/adapters/PostgreSQLAdapter.js.map +0 -1
  422. package/dist/src/adapters/PrismaAdapter.js.map +0 -1
  423. package/dist/src/adapters/RedisAdapter.js.map +0 -1
  424. package/dist/src/adapters/SQLiteAdapter.js.map +0 -1
  425. package/dist/src/adapters/index.js.map +0 -1
  426. package/dist/src/constants/index.js.map +0 -1
  427. package/dist/src/core/Agent.d.ts.map +0 -1
  428. package/dist/src/core/Agent.js.map +0 -1
  429. package/dist/src/core/Events.js.map +0 -1
  430. package/dist/src/core/PersistenceManager.js.map +0 -1
  431. package/dist/src/core/PromptComposer.d.ts.map +0 -1
  432. package/dist/src/core/PromptComposer.js.map +0 -1
  433. package/dist/src/core/ResponseEngine.js +0 -80
  434. package/dist/src/core/ResponseEngine.js.map +0 -1
  435. package/dist/src/core/ResponseModal.d.ts.map +0 -1
  436. package/dist/src/core/ResponseModal.js.map +0 -1
  437. package/dist/src/core/ResponsePipeline.d.ts.map +0 -1
  438. package/dist/src/core/ResponsePipeline.js.map +0 -1
  439. package/dist/src/core/Route.d.ts.map +0 -1
  440. package/dist/src/core/Route.js.map +0 -1
  441. package/dist/src/core/RoutingEngine.d.ts.map +0 -1
  442. package/dist/src/core/RoutingEngine.js.map +0 -1
  443. package/dist/src/core/SessionManager.js.map +0 -1
  444. package/dist/src/core/Step.d.ts.map +0 -1
  445. package/dist/src/core/Step.js.map +0 -1
  446. package/dist/src/core/ToolManager.js.map +0 -1
  447. package/dist/src/index.d.ts.map +0 -1
  448. package/dist/src/index.js.map +0 -1
  449. package/dist/src/providers/AnthropicProvider.js.map +0 -1
  450. package/dist/src/providers/GeminiProvider.js.map +0 -1
  451. package/dist/src/providers/OpenAIProvider.js.map +0 -1
  452. package/dist/src/providers/OpenRouterProvider.js.map +0 -1
  453. package/dist/src/providers/index.js.map +0 -1
  454. package/dist/src/types/agent.d.ts.map +0 -1
  455. package/dist/src/types/agent.js.map +0 -1
  456. package/dist/src/types/history.js.map +0 -1
  457. package/dist/src/types/index.js.map +0 -1
  458. package/dist/src/types/persistence.js.map +0 -1
  459. package/dist/src/types/route.d.ts.map +0 -1
  460. package/dist/src/types/template.d.ts +0 -30
  461. package/dist/src/types/template.d.ts.map +0 -1
  462. package/dist/src/types/tool.js.map +0 -1
  463. package/dist/src/utils/clone.js.map +0 -1
  464. package/dist/src/utils/event.js.map +0 -1
  465. package/dist/src/utils/history.js.map +0 -1
  466. package/dist/src/utils/id.js.map +0 -1
  467. package/dist/src/utils/index.d.ts.map +0 -1
  468. package/dist/src/utils/index.js.map +0 -1
  469. package/dist/src/utils/logger.js.map +0 -1
  470. package/dist/src/utils/retry.d.ts.map +0 -1
  471. package/dist/src/utils/retry.js.map +0 -1
  472. package/dist/src/utils/session.js.map +0 -1
  473. package/dist/src/utils/template.d.ts.map +0 -1
  474. package/dist/src/utils/template.js.map +0 -1
  475. /package/dist/{cjs/src/adapters → adapters}/MemoryAdapter.d.ts +0 -0
  476. /package/dist/{src/adapters → adapters}/MemoryAdapter.js +0 -0
  477. /package/dist/{cjs/src/adapters → adapters}/MongoAdapter.d.ts +0 -0
  478. /package/dist/{src/adapters → adapters}/MongoAdapter.js +0 -0
  479. /package/dist/{cjs/src/adapters → adapters}/OpenSearchAdapter.d.ts +0 -0
  480. /package/dist/{src/adapters → adapters}/OpenSearchAdapter.js +0 -0
  481. /package/dist/{cjs/src/adapters → adapters}/PostgreSQLAdapter.d.ts +0 -0
  482. /package/dist/{src/adapters → adapters}/PostgreSQLAdapter.js +0 -0
  483. /package/dist/{cjs/src/adapters → adapters}/PrismaAdapter.d.ts +0 -0
  484. /package/dist/{cjs/src/adapters → adapters}/RedisAdapter.d.ts +0 -0
  485. /package/dist/{cjs/src/adapters → adapters}/SQLiteAdapter.d.ts +0 -0
  486. /package/dist/{src/adapters → adapters}/SQLiteAdapter.js +0 -0
  487. /package/dist/{cjs/src/adapters → adapters}/index.d.ts +0 -0
  488. /package/dist/{src/adapters → adapters}/index.js +0 -0
  489. /package/dist/{src → cjs}/adapters/MemoryAdapter.d.ts +0 -0
  490. /package/dist/{src → cjs}/adapters/MemoryAdapter.d.ts.map +0 -0
  491. /package/dist/cjs/{src/adapters → adapters}/MemoryAdapter.js +0 -0
  492. /package/dist/{src → cjs}/adapters/MongoAdapter.d.ts +0 -0
  493. /package/dist/{src → cjs}/adapters/MongoAdapter.d.ts.map +0 -0
  494. /package/dist/cjs/{src/adapters → adapters}/MongoAdapter.js +0 -0
  495. /package/dist/{src → cjs}/adapters/OpenSearchAdapter.d.ts +0 -0
  496. /package/dist/{src → cjs}/adapters/OpenSearchAdapter.d.ts.map +0 -0
  497. /package/dist/cjs/{src/adapters → adapters}/OpenSearchAdapter.js +0 -0
  498. /package/dist/{src → cjs}/adapters/PostgreSQLAdapter.d.ts +0 -0
  499. /package/dist/{src → cjs}/adapters/PostgreSQLAdapter.d.ts.map +0 -0
  500. /package/dist/cjs/{src/adapters → adapters}/PostgreSQLAdapter.js +0 -0
  501. /package/dist/{src → cjs}/adapters/PrismaAdapter.d.ts +0 -0
  502. /package/dist/{src → cjs}/adapters/RedisAdapter.d.ts +0 -0
  503. /package/dist/{src → cjs}/adapters/RedisAdapter.d.ts.map +0 -0
  504. /package/dist/{src → cjs}/adapters/SQLiteAdapter.d.ts +0 -0
  505. /package/dist/{src → cjs}/adapters/SQLiteAdapter.d.ts.map +0 -0
  506. /package/dist/cjs/{src/adapters → adapters}/SQLiteAdapter.js +0 -0
  507. /package/dist/{src → cjs}/adapters/index.d.ts +0 -0
  508. /package/dist/{src → cjs}/adapters/index.d.ts.map +0 -0
  509. /package/dist/cjs/{src/adapters → adapters}/index.js +0 -0
  510. /package/dist/cjs/{src/constants → constants}/index.d.ts +0 -0
  511. /package/dist/{src → cjs}/constants/index.d.ts.map +0 -0
  512. /package/dist/cjs/{src/constants → constants}/index.js +0 -0
  513. /package/dist/cjs/{src/core → core}/Events.d.ts +0 -0
  514. /package/dist/{src → cjs}/core/Events.d.ts.map +0 -0
  515. /package/dist/cjs/{src/core → core}/Events.js +0 -0
  516. /package/dist/cjs/{src/core → core}/PersistenceManager.d.ts +0 -0
  517. /package/dist/{src → cjs}/core/PersistenceManager.d.ts.map +0 -0
  518. /package/dist/cjs/{src/core → core}/PersistenceManager.js +0 -0
  519. /package/dist/cjs/{src/core → core}/ResponseEngine.d.ts +0 -0
  520. /package/dist/cjs/{src/core → core}/SessionManager.d.ts +0 -0
  521. /package/dist/{src → cjs}/core/SessionManager.d.ts.map +0 -0
  522. /package/dist/cjs/{src/core → core}/SessionManager.js +0 -0
  523. /package/dist/cjs/{src/core → core}/ToolManager.d.ts +0 -0
  524. /package/dist/{src → cjs}/core/ToolManager.d.ts.map +0 -0
  525. /package/dist/cjs/{src/core → core}/ToolManager.js +0 -0
  526. /package/dist/cjs/{src/providers → providers}/AnthropicProvider.d.ts +0 -0
  527. /package/dist/{src → cjs}/providers/AnthropicProvider.d.ts.map +0 -0
  528. /package/dist/cjs/{src/providers → providers}/GeminiProvider.d.ts +0 -0
  529. /package/dist/cjs/{src/providers → providers}/OpenAIProvider.d.ts +0 -0
  530. /package/dist/{src → cjs}/providers/OpenAIProvider.d.ts.map +0 -0
  531. /package/dist/cjs/{src/providers → providers}/OpenRouterProvider.d.ts +0 -0
  532. /package/dist/{src → cjs}/providers/OpenRouterProvider.d.ts.map +0 -0
  533. /package/dist/cjs/{src/providers → providers}/index.d.ts +0 -0
  534. /package/dist/{src → cjs}/providers/index.d.ts.map +0 -0
  535. /package/dist/cjs/{src/providers → providers}/index.js +0 -0
  536. /package/dist/cjs/{src/types → types}/agent.js +0 -0
  537. /package/dist/cjs/{src/types → types}/ai.d.ts +0 -0
  538. /package/dist/{src → cjs}/types/ai.d.ts.map +0 -0
  539. /package/dist/cjs/{src/types → types}/ai.js +0 -0
  540. /package/dist/cjs/{src/types → types}/history.d.ts +0 -0
  541. /package/dist/{src → cjs}/types/history.d.ts.map +0 -0
  542. /package/dist/cjs/{src/types → types}/history.js +0 -0
  543. /package/dist/cjs/{src/types → types}/persistence.d.ts +0 -0
  544. /package/dist/{src → cjs}/types/persistence.d.ts.map +0 -0
  545. /package/dist/cjs/{src/types → types}/persistence.js +0 -0
  546. /package/dist/cjs/{src/types → types}/route.js +0 -0
  547. /package/dist/cjs/{src/types → types}/routing.d.ts +0 -0
  548. /package/dist/{src → cjs}/types/routing.d.ts.map +0 -0
  549. /package/dist/cjs/{src/types → types}/routing.js +0 -0
  550. /package/dist/{src → cjs}/types/routing.js.map +0 -0
  551. /package/dist/cjs/{src/types → types}/schema.d.ts +0 -0
  552. /package/dist/{src → cjs}/types/schema.d.ts.map +0 -0
  553. /package/dist/cjs/{src/types → types}/schema.js +0 -0
  554. /package/dist/{src → cjs}/types/schema.js.map +0 -0
  555. /package/dist/cjs/{src/types → types}/session.d.ts +0 -0
  556. /package/dist/{src → cjs}/types/session.d.ts.map +0 -0
  557. /package/dist/cjs/{src/types → types}/session.js +0 -0
  558. /package/dist/cjs/{src/types → types}/template.js +0 -0
  559. /package/dist/{src → cjs}/types/template.js.map +0 -0
  560. /package/dist/cjs/{src/types → types}/tool.d.ts +0 -0
  561. /package/dist/{src → cjs}/types/tool.d.ts.map +0 -0
  562. /package/dist/cjs/{src/types → types}/tool.js +0 -0
  563. /package/dist/cjs/{src/utils → utils}/clone.d.ts +0 -0
  564. /package/dist/{src → cjs}/utils/clone.d.ts.map +0 -0
  565. /package/dist/cjs/{src/utils → utils}/clone.js +0 -0
  566. /package/dist/cjs/{src/utils → utils}/event.d.ts +0 -0
  567. /package/dist/{src → cjs}/utils/event.d.ts.map +0 -0
  568. /package/dist/cjs/{src/utils → utils}/event.js +0 -0
  569. /package/dist/cjs/{src/utils → utils}/history.d.ts +0 -0
  570. /package/dist/{src → cjs}/utils/history.d.ts.map +0 -0
  571. /package/dist/cjs/{src/utils → utils}/history.js +0 -0
  572. /package/dist/cjs/{src/utils → utils}/id.d.ts +0 -0
  573. /package/dist/{src → cjs}/utils/id.d.ts.map +0 -0
  574. /package/dist/cjs/{src/utils → utils}/id.js +0 -0
  575. /package/dist/cjs/{src/utils → utils}/logger.d.ts +0 -0
  576. /package/dist/{src → cjs}/utils/logger.d.ts.map +0 -0
  577. /package/dist/cjs/{src/utils → utils}/logger.js +0 -0
  578. /package/dist/cjs/{src/utils → utils}/session.d.ts +0 -0
  579. /package/dist/{src → cjs}/utils/session.d.ts.map +0 -0
  580. /package/dist/cjs/{src/utils → utils}/session.js +0 -0
  581. /package/dist/{src/constants → constants}/index.d.ts +0 -0
  582. /package/dist/{src/constants → constants}/index.js +0 -0
  583. /package/dist/{src/core → core}/Events.d.ts +0 -0
  584. /package/dist/{src/core → core}/Events.js +0 -0
  585. /package/dist/{src/core → core}/PersistenceManager.d.ts +0 -0
  586. /package/dist/{src/core → core}/PersistenceManager.js +0 -0
  587. /package/dist/{src/core → core}/ResponseEngine.d.ts +0 -0
  588. /package/dist/{src/core → core}/SessionManager.d.ts +0 -0
  589. /package/dist/{src/core → core}/SessionManager.js +0 -0
  590. /package/dist/{src/core → core}/ToolManager.d.ts +0 -0
  591. /package/dist/{src/core → core}/ToolManager.js +0 -0
  592. /package/dist/{src/providers → providers}/AnthropicProvider.d.ts +0 -0
  593. /package/dist/{src/providers → providers}/GeminiProvider.d.ts +0 -0
  594. /package/dist/{src/providers → providers}/OpenAIProvider.d.ts +0 -0
  595. /package/dist/{src/providers → providers}/OpenRouterProvider.d.ts +0 -0
  596. /package/dist/{src/providers → providers}/index.d.ts +0 -0
  597. /package/dist/{src/providers → providers}/index.js +0 -0
  598. /package/dist/{src/types → types}/agent.js +0 -0
  599. /package/dist/{src/types → types}/ai.d.ts +0 -0
  600. /package/dist/{src/types → types}/ai.js +0 -0
  601. /package/dist/{src/types → types}/history.d.ts +0 -0
  602. /package/dist/{src/types → types}/history.js +0 -0
  603. /package/dist/{src/types → types}/persistence.d.ts +0 -0
  604. /package/dist/{src/types → types}/persistence.js +0 -0
  605. /package/dist/{src/types → types}/route.js +0 -0
  606. /package/dist/{src/types → types}/routing.d.ts +0 -0
  607. /package/dist/{src/types → types}/routing.js +0 -0
  608. /package/dist/{src/types → types}/schema.d.ts +0 -0
  609. /package/dist/{src/types → types}/schema.js +0 -0
  610. /package/dist/{src/types → types}/session.d.ts +0 -0
  611. /package/dist/{src/types → types}/session.js +0 -0
  612. /package/dist/{src/types → types}/template.js +0 -0
  613. /package/dist/{src/types → types}/tool.d.ts +0 -0
  614. /package/dist/{src/types → types}/tool.js +0 -0
  615. /package/dist/{src/utils → utils}/clone.d.ts +0 -0
  616. /package/dist/{src/utils → utils}/clone.js +0 -0
  617. /package/dist/{src/utils → utils}/event.d.ts +0 -0
  618. /package/dist/{src/utils → utils}/event.js +0 -0
  619. /package/dist/{src/utils → utils}/history.d.ts +0 -0
  620. /package/dist/{src/utils → utils}/history.js +0 -0
  621. /package/dist/{src/utils → utils}/id.d.ts +0 -0
  622. /package/dist/{src/utils → utils}/id.js +0 -0
  623. /package/dist/{src/utils → utils}/logger.d.ts +0 -0
  624. /package/dist/{src/utils → utils}/logger.js +0 -0
  625. /package/dist/{src/utils → utils}/session.d.ts +0 -0
  626. /package/dist/{src/utils → utils}/session.js +0 -0
@@ -9,7 +9,10 @@ const types_1 = require("../types");
9
9
  const Step_1 = require("./Step");
10
10
  const ResponseEngine_1 = require("./ResponseEngine");
11
11
  const ResponsePipeline_1 = require("./ResponsePipeline");
12
+ const BatchExecutor_1 = require("./BatchExecutor");
13
+ const BatchPromptBuilder_1 = require("./BatchPromptBuilder");
12
14
  const utils_1 = require("../utils");
15
+ const template_1 = require("../utils/template");
13
16
  const constants_1 = require("../constants");
14
17
  /**
15
18
  * Error class for response generation failures
@@ -52,6 +55,10 @@ class ResponseModal {
52
55
  // Initialize response pipeline with agent dependencies
53
56
  this.responsePipeline = new ResponsePipeline_1.ResponsePipeline(this.agent.getAgentOptions(), () => this.agent.getRoutes(), // Pass a function to get routes dynamically
54
57
  this.agent.getTools(), this.agent.getRoutingEngine(), this.agent.updateContext.bind(this.agent), this.agent.getUpdateDataMethod(), this.agent.updateCollectedData.bind(this.agent), this.getToolManager());
58
+ // Initialize batch executor for multi-step execution
59
+ this.batchExecutor = new BatchExecutor_1.BatchExecutor();
60
+ // Initialize batch prompt builder for combined prompts
61
+ this.batchPromptBuilder = new BatchPromptBuilder_1.BatchPromptBuilder();
55
62
  }
56
63
  /**
57
64
  * Generate a non-streaming response using unified logic
@@ -272,6 +279,7 @@ class ResponseModal {
272
279
  throw ResponseGenerationError.fromError(error, 'step_preparation', params, { session, effectiveContext });
273
280
  }
274
281
  // PHASE 2: ROUTING + STEP SELECTION - Determine which route and step to use
282
+ // Also performs pre-extraction and batch determination
275
283
  let routingResult;
276
284
  try {
277
285
  routingResult = await this.handleUnifiedRoutingAndStepSelection({
@@ -292,6 +300,9 @@ class ResponseModal {
292
300
  selectedStep: routingResult.selectedStep,
293
301
  responseDirectives: routingResult.responseDirectives,
294
302
  isRouteComplete: routingResult.isRouteComplete,
303
+ batchSteps: routingResult.batchSteps,
304
+ batchStoppedReason: routingResult.batchStoppedReason,
305
+ batchStoppedAtStep: routingResult.batchStoppedAtStep,
295
306
  };
296
307
  }
297
308
  catch (error) {
@@ -317,31 +328,156 @@ class ResponseModal {
317
328
  context: params.context,
318
329
  signal: params.signal,
319
330
  });
331
+ let updatedSession = routingResult.session;
332
+ let isRouteComplete = routingResult.isRouteComplete;
333
+ // PRE-EXTRACTION: If entering a route that collects data, extract data from user message first
334
+ // This allows us to skip steps whose data is already provided
335
+ // Requirement 3.1: Perform Pre_Extraction before determining the Batch
336
+ if (routingResult.selectedRoute && !isRouteComplete) {
337
+ // Always pre-extract when route collects data (not just on new route entry)
338
+ // This ensures batch determination has the most up-to-date data
339
+ if (this.shouldPreExtractData(routingResult.selectedRoute)) {
340
+ utils_1.logger.debug(`[ResponseModal] Pre-extracting data for route: ${routingResult.selectedRoute.title}`);
341
+ const extractedData = await this.preExtractRouteData({
342
+ route: routingResult.selectedRoute,
343
+ history: params.history,
344
+ context: params.context,
345
+ session: updatedSession,
346
+ signal: params.signal,
347
+ });
348
+ if (extractedData && Object.keys(extractedData).length > 0) {
349
+ utils_1.logger.debug(`[ResponseModal] Pre-extracted data:`, extractedData);
350
+ // Requirement 3.3: Merge pre-extracted data into session before batch determination
351
+ updatedSession = (0, utils_1.mergeCollected)(updatedSession, extractedData);
352
+ // Also update agent's collected data
353
+ await this.agent.updateCollectedData(extractedData);
354
+ // Re-check route completion after pre-extraction
355
+ const allRequiredFieldsCollected = routingResult.selectedRoute.isComplete(updatedSession.data || {});
356
+ if (allRequiredFieldsCollected) {
357
+ utils_1.logger.debug(`[ResponseModal] Route ${routingResult.selectedRoute.title} completed after pre-extraction`);
358
+ isRouteComplete = true;
359
+ }
360
+ }
361
+ }
362
+ }
363
+ // BATCH DETERMINATION: Use BatchExecutor to determine which steps can execute together
364
+ // Requirement 3.4: Pre-extraction results affect batch determination
365
+ let batchSteps;
366
+ let batchStoppedReason;
367
+ let batchStoppedAtStep;
368
+ if (routingResult.selectedRoute && !isRouteComplete) {
369
+ // Determine current step position for batch determination
370
+ const currentStep = routingResult.selectedStep ||
371
+ (updatedSession.currentStep ? routingResult.selectedRoute.getStep(updatedSession.currentStep.id) : undefined);
372
+ utils_1.logger.debug(`[ResponseModal] Determining batch starting from step: ${currentStep?.id || 'initial'}`);
373
+ const batchResult = await this.batchExecutor.determineBatch({
374
+ route: routingResult.selectedRoute,
375
+ currentStep,
376
+ sessionData: updatedSession.data || {},
377
+ context: params.context,
378
+ });
379
+ batchSteps = batchResult.steps;
380
+ batchStoppedReason = batchResult.stoppedReason;
381
+ batchStoppedAtStep = batchResult.stoppedAtStep;
382
+ utils_1.logger.debug(`[ResponseModal] Batch determined: ${batchSteps.length} steps, stopped reason: ${batchStoppedReason}`);
383
+ }
320
384
  // Determine next step using pipeline method for consistency
321
- const stepResult = this.responsePipeline.determineNextStep({
385
+ const stepResult = await this.responsePipeline.determineNextStep({
322
386
  selectedRoute: routingResult.selectedRoute,
323
387
  selectedStep: routingResult.selectedStep,
324
- session: routingResult.session,
325
- isRouteComplete: routingResult.isRouteComplete,
388
+ session: updatedSession, // Use updated session with pre-extracted data
389
+ isRouteComplete, // Use updated completion status
326
390
  });
327
391
  return {
328
392
  selectedRoute: routingResult.selectedRoute,
329
393
  selectedStep: stepResult.nextStep, // Use the determined next step
330
394
  responseDirectives: routingResult.responseDirectives,
331
395
  session: stepResult.session,
332
- isRouteComplete: routingResult.isRouteComplete,
396
+ isRouteComplete, // Use updated completion status
397
+ batchSteps,
398
+ batchStoppedReason,
399
+ batchStoppedAtStep,
333
400
  };
334
401
  }
335
402
  catch (error) {
336
403
  throw ResponseGenerationError.fromError(error, 'routing_optimization', params);
337
404
  }
338
405
  }
406
+ /**
407
+ * Check if a route should pre-extract data before determining the initial step
408
+ * @private
409
+ */
410
+ shouldPreExtractData(route) {
411
+ // Pre-extract if route has declared required or optional fields
412
+ if (route.requiredFields && route.requiredFields.length > 0) {
413
+ return true;
414
+ }
415
+ if (route.optionalFields && route.optionalFields.length > 0) {
416
+ return true;
417
+ }
418
+ // Pre-extract if any step in the route collects data
419
+ const steps = route.getAllSteps();
420
+ const hasDataCollectionSteps = steps.some(step => step.collect && step.collect.length > 0);
421
+ return hasDataCollectionSteps;
422
+ }
423
+ /**
424
+ * Pre-extract data from user message when entering a route
425
+ * This allows skipping steps whose data is already provided
426
+ * @private
427
+ */
428
+ async preExtractRouteData(params) {
429
+ const { route, history, context, signal } = params;
430
+ // Build a schema for data extraction based on route's fields
431
+ const extractionSchema = this.agent.getSchema();
432
+ if (!extractionSchema) {
433
+ utils_1.logger.warn(`[ResponseModal] No schema available for pre-extraction`);
434
+ return {};
435
+ }
436
+ // Get last user message
437
+ const lastMessage = (0, utils_1.getLastMessageFromHistory)(history);
438
+ // Build extraction prompt
439
+ const extractionPrompt = [
440
+ `Extract any relevant information from the user's message that matches the following data fields.`,
441
+ `Only extract information that is explicitly stated or clearly implied.`,
442
+ ``,
443
+ `User's message: "${lastMessage}"`,
444
+ ``,
445
+ `Extract data for these fields if present:`,
446
+ ];
447
+ // Add field descriptions
448
+ if (route.requiredFields) {
449
+ extractionPrompt.push(`Required fields: ${route.requiredFields.join(', ')}`);
450
+ }
451
+ if (route.optionalFields) {
452
+ extractionPrompt.push(`Optional fields: ${route.optionalFields.join(', ')}`);
453
+ }
454
+ extractionPrompt.push(``, `Return ONLY the extracted data as JSON. If no data can be extracted, return an empty object {}.`);
455
+ // Call AI to extract data
456
+ const agentOptions = this.agent.getAgentOptions();
457
+ try {
458
+ const result = await agentOptions.provider.generateMessage({
459
+ prompt: extractionPrompt.join('\n'),
460
+ history,
461
+ context,
462
+ signal,
463
+ parameters: {
464
+ jsonSchema: extractionSchema,
465
+ schemaName: 'data_extraction',
466
+ },
467
+ });
468
+ return result.structured || {};
469
+ }
470
+ catch (error) {
471
+ utils_1.logger.error(`[ResponseModal] Pre-extraction failed:`, error);
472
+ return {};
473
+ }
474
+ }
339
475
  /**
340
476
  * Unified response generation for non-streaming responses
341
477
  * @private
342
478
  */
343
479
  async generateUnifiedResponse(responseContext) {
344
- const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete } = responseContext;
480
+ const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete, batchSteps, batchStoppedReason, } = responseContext;
345
481
  let session = initialSession;
346
482
  // Get last user message (needed for both route and completion handling)
347
483
  // Convert HistoryItem[] to Event[] for internal processing
@@ -349,35 +485,79 @@ class ResponseModal {
349
485
  const lastMessageText = (0, utils_1.getLastMessageFromHistory)(historyEvents);
350
486
  let message;
351
487
  let toolCalls = undefined;
488
+ let executedSteps;
489
+ let stoppedReason;
352
490
  if (selectedRoute && !isRouteComplete) {
353
- // Handle normal route processing
354
- const result = await this.processRouteResponse({
355
- selectedRoute,
356
- selectedStep,
357
- responseDirectives,
358
- session,
359
- history,
360
- context: effectiveContext,
361
- lastMessageText,
362
- historyEvents,
363
- signal: responseContext.history ? undefined : undefined, // TODO: Fix signal passing
364
- });
365
- message = result.message;
366
- toolCalls = result.toolCalls;
367
- session = result.session;
491
+ // Check if we have batch steps to execute
492
+ if (batchSteps && batchSteps.length > 0) {
493
+ // BATCH EXECUTION: Execute multiple steps in a single LLM call
494
+ utils_1.logger.debug(`[ResponseModal] Executing batch of ${batchSteps.length} steps`);
495
+ const batchResult = await this.executeBatchResponse({
496
+ selectedRoute,
497
+ batchSteps,
498
+ responseDirectives,
499
+ session,
500
+ history,
501
+ context: effectiveContext,
502
+ historyEvents,
503
+ });
504
+ message = batchResult.message;
505
+ toolCalls = batchResult.toolCalls;
506
+ session = batchResult.session;
507
+ executedSteps = batchResult.executedSteps;
508
+ stoppedReason = batchStoppedReason;
509
+ }
510
+ else {
511
+ // SINGLE STEP EXECUTION: Fall back to single-step processing
512
+ // This happens when batch determination returns empty (first step needs input)
513
+ const result = await this.processRouteResponse({
514
+ selectedRoute,
515
+ selectedStep,
516
+ responseDirectives,
517
+ session,
518
+ history,
519
+ context: effectiveContext,
520
+ lastMessageText,
521
+ historyEvents,
522
+ signal: undefined,
523
+ });
524
+ message = result.message;
525
+ toolCalls = result.toolCalls;
526
+ session = result.session;
527
+ // Track executed step for single-step execution
528
+ if (selectedStep) {
529
+ executedSteps = [{
530
+ id: selectedStep.id,
531
+ routeId: selectedRoute.id,
532
+ }];
533
+ }
534
+ stoppedReason = batchStoppedReason || 'needs_input';
535
+ }
368
536
  }
369
537
  else if (isRouteComplete && selectedRoute) {
370
538
  // Handle route completion
371
- message = await this.handleRouteCompletion({
372
- selectedRoute,
373
- session,
374
- context: effectiveContext,
375
- lastMessageText,
376
- historyEvents,
377
- });
378
- // Set step to END_ROUTE marker
379
- session = (0, utils_1.enterStep)(session, constants_1.END_ROUTE_ID, "Route completed");
380
- utils_1.logger.debug(`[ResponseModal] Route ${selectedRoute.title} completed. Entered END_ROUTE step.`);
539
+ utils_1.logger.debug(`[ResponseModal] Generating completion message for route: ${selectedRoute.title}`);
540
+ try {
541
+ message = await this.handleRouteCompletion({
542
+ selectedRoute,
543
+ session,
544
+ context: effectiveContext,
545
+ lastMessageText,
546
+ historyEvents,
547
+ signal: undefined,
548
+ });
549
+ // Set step to END_ROUTE marker
550
+ session = (0, utils_1.enterStep)(session, constants_1.END_ROUTE_ID, "Route completed");
551
+ stoppedReason = 'route_complete';
552
+ utils_1.logger.debug(`[ResponseModal] Route ${selectedRoute.title} completed. Entered END_ROUTE step.`);
553
+ }
554
+ catch (error) {
555
+ utils_1.logger.error(`[ResponseModal] Error generating completion message:`, error);
556
+ // Fallback to simple completion message
557
+ message = `Thank you! I've recorded all the information for your ${selectedRoute.title.toLowerCase()}.`;
558
+ session = (0, utils_1.enterStep)(session, constants_1.END_ROUTE_ID, "Route completed");
559
+ stoppedReason = 'route_complete';
560
+ }
381
561
  }
382
562
  else {
383
563
  // Fallback: No routes defined, generate a simple response
@@ -386,37 +566,268 @@ class ResponseModal {
386
566
  context: effectiveContext,
387
567
  session,
388
568
  });
569
+ // For fallback responses, set empty executedSteps and no stoppedReason
570
+ // since there's no route/step execution happening
571
+ executedSteps = [];
572
+ stoppedReason = undefined;
389
573
  }
574
+ // Ensure response structure completeness (Requirement 8.1, 8.2, 8.3)
575
+ // - executedSteps: array of steps executed (empty array if none)
576
+ // - stoppedReason: why execution stopped (undefined for fallback)
577
+ // - session.currentStep: reflects final step position
390
578
  return {
391
579
  message,
392
580
  session,
393
581
  toolCalls,
394
582
  isRouteComplete,
583
+ executedSteps: executedSteps || [],
584
+ stoppedReason,
585
+ };
586
+ }
587
+ /**
588
+ * Execute a batch of steps with a single LLM call
589
+ *
590
+ * This method:
591
+ * 1. Executes all prepare hooks for steps in the batch (in order)
592
+ * 2. Builds a combined prompt using BatchPromptBuilder
593
+ * 3. Makes a single LLM call
594
+ * 4. Collects data from the response for all steps
595
+ * 5. Executes all finalize hooks for steps in the batch (in order)
596
+ *
597
+ * @private
598
+ * **Validates: Requirements 1.1, 4.4, 5.1, 5.2**
599
+ */
600
+ async executeBatchResponse(params) {
601
+ const { selectedRoute, batchSteps, history, context, historyEvents, signal } = params;
602
+ let session = params.session;
603
+ utils_1.logger.debug(`[ResponseModal] Starting batch execution for ${batchSteps.length} steps`);
604
+ // Create hook executor function
605
+ const executeHook = async (hook, hookContext, data, step) => {
606
+ // Find the route for this step
607
+ const route = selectedRoute;
608
+ // Convert StepOptions to Step if needed for executePrepareFinalize
609
+ const stepInstance = step?.id ? route.getStep(step.id) : undefined;
610
+ await this.executePrepareFinalize(hook, hookContext, data, route, stepInstance);
611
+ };
612
+ // PHASE 1: Execute all prepare hooks (Requirement 5.1)
613
+ utils_1.logger.debug(`[ResponseModal] Executing prepare hooks for batch`);
614
+ const prepareResult = await this.batchExecutor.executePrepareHooks({
615
+ steps: batchSteps,
616
+ context,
617
+ data: session.data,
618
+ executeHook,
619
+ });
620
+ if (!prepareResult.success) {
621
+ // Prepare hook failed - return error response
622
+ utils_1.logger.error(`[ResponseModal] Prepare hook failed:`, prepareResult.error);
623
+ throw new ResponseGenerationError(`Prepare hook failed: ${prepareResult.error?.message}`, {
624
+ phase: 'prepare_hooks',
625
+ context: {
626
+ stepId: prepareResult.error?.stepId,
627
+ executedSteps: prepareResult.executedSteps,
628
+ }
629
+ });
630
+ }
631
+ // PHASE 2: Build combined prompt using BatchPromptBuilder (Requirement 4.4)
632
+ utils_1.logger.debug(`[ResponseModal] Building batch prompt`);
633
+ const batchPromptResult = await this.batchPromptBuilder.buildBatchPrompt({
634
+ steps: batchSteps,
635
+ route: selectedRoute,
636
+ history: historyEvents,
637
+ context,
638
+ session,
639
+ agentOptions: this.agent.getAgentOptions(),
640
+ });
641
+ utils_1.logger.debug(`[ResponseModal] Batch prompt built with ${batchPromptResult.stepCount} steps, collecting: ${batchPromptResult.collectFields.join(', ')}`);
642
+ // Build response schema for batch (includes all collect fields)
643
+ const responseSchema = this.buildBatchResponseSchema(batchPromptResult.collectFields);
644
+ // Collect available tools for AI (from all steps in batch)
645
+ const availableTools = this.collectBatchAvailableTools(selectedRoute, batchSteps);
646
+ // PHASE 3: Make single LLM call (Requirement 4.4)
647
+ utils_1.logger.debug(`[ResponseModal] Making LLM call for batch`);
648
+ const agentOptions = this.agent.getAgentOptions();
649
+ const result = await agentOptions.provider.generateMessage({
650
+ prompt: batchPromptResult.prompt,
651
+ history: historyEvents,
652
+ context,
653
+ tools: availableTools,
654
+ signal,
655
+ parameters: responseSchema ? { jsonSchema: responseSchema, schemaName: "batch_response" } : undefined,
656
+ });
657
+ let message = result.structured?.message || result.message;
658
+ let toolCalls = result.structured?.toolCalls;
659
+ utils_1.logger.debug(`[ResponseModal] LLM response received for batch`);
660
+ // Execute tools if any
661
+ if (toolCalls && toolCalls.length > 0) {
662
+ const toolResult = await this.executeUnifiedToolLoop({
663
+ toolCalls,
664
+ context,
665
+ session,
666
+ history,
667
+ selectedRoute,
668
+ responsePrompt: batchPromptResult.prompt,
669
+ availableTools,
670
+ responseSchema,
671
+ signal,
672
+ });
673
+ session = toolResult.session;
674
+ toolCalls = toolResult.finalToolCalls;
675
+ if (toolResult.finalMessage) {
676
+ message = toolResult.finalMessage;
677
+ }
678
+ }
679
+ // PHASE 4: Collect data from response for all steps (Requirement 6.1, 6.2, 6.3)
680
+ utils_1.logger.debug(`[ResponseModal] Collecting batch data`);
681
+ const collectResult = this.batchExecutor.collectBatchData({
682
+ steps: batchSteps,
683
+ llmResponse: result.structured || {},
684
+ session,
685
+ schema: this.agent.getSchema(),
686
+ });
687
+ session = collectResult.session;
688
+ if (collectResult.collectedData && Object.keys(collectResult.collectedData).length > 0) {
689
+ // Update agent's collected data
690
+ await this.agent.updateCollectedData(collectResult.collectedData);
691
+ utils_1.logger.debug(`[ResponseModal] Batch collected data:`, collectResult.collectedData);
692
+ }
693
+ if (collectResult.validationErrors && collectResult.validationErrors.length > 0) {
694
+ utils_1.logger.warn(`[ResponseModal] Batch data validation errors:`, collectResult.validationErrors);
695
+ }
696
+ // Update session to final step position
697
+ const lastStep = batchSteps[batchSteps.length - 1];
698
+ if (lastStep?.id) {
699
+ session = (0, utils_1.enterStep)(session, lastStep.id, lastStep.description);
700
+ utils_1.logger.debug(`[ResponseModal] Updated session to final batch step: ${lastStep.id}`);
701
+ }
702
+ // PHASE 5: Execute all finalize hooks (Requirement 5.2)
703
+ utils_1.logger.debug(`[ResponseModal] Executing finalize hooks for batch`);
704
+ const finalizeResult = await this.batchExecutor.executeFinalizeHooks({
705
+ steps: batchSteps,
706
+ context,
707
+ data: session.data,
708
+ executeHook,
709
+ });
710
+ if (finalizeResult.errors && finalizeResult.errors.length > 0) {
711
+ // Log finalize errors but don't fail (Requirement 5.5)
712
+ utils_1.logger.warn(`[ResponseModal] Some finalize hooks failed:`, finalizeResult.errors);
713
+ }
714
+ // Build executed steps list
715
+ const executedSteps = batchSteps
716
+ .filter(step => step.id)
717
+ .map(step => ({
718
+ id: step.id,
719
+ routeId: selectedRoute.id,
720
+ }));
721
+ utils_1.logger.debug(`[ResponseModal] Batch execution complete. Executed ${executedSteps.length} steps`);
722
+ return {
723
+ message,
724
+ toolCalls,
725
+ session,
726
+ executedSteps,
727
+ };
728
+ }
729
+ /**
730
+ * Build response schema for batch execution
731
+ * @private
732
+ */
733
+ buildBatchResponseSchema(collectFields) {
734
+ const properties = {
735
+ message: {
736
+ type: "string",
737
+ description: "Your response to the user",
738
+ },
739
+ };
740
+ // Add collect fields to schema
741
+ for (const field of collectFields) {
742
+ properties[field] = {
743
+ type: "string",
744
+ description: `Collected value for ${field}`,
745
+ };
746
+ }
747
+ return {
748
+ type: "object",
749
+ properties,
750
+ required: ["message"],
751
+ additionalProperties: true,
395
752
  };
396
753
  }
754
+ /**
755
+ * Collect available tools from all steps in the batch
756
+ * @private
757
+ */
758
+ collectBatchAvailableTools(route, batchSteps) {
759
+ const availableTools = new Map();
760
+ // Add agent-level tools
761
+ this.agent.getTools().forEach((tool) => {
762
+ availableTools.set(tool.id, tool);
763
+ });
764
+ // Add route-level tools
765
+ route.getTools().forEach((tool) => {
766
+ availableTools.set(tool.id, tool);
767
+ });
768
+ // Add step-level tools from all batch steps
769
+ for (const step of batchSteps) {
770
+ if (step.tools) {
771
+ for (const toolRef of step.tools) {
772
+ if (typeof toolRef === "string") {
773
+ // Reference to registered tool - already in availableTools
774
+ }
775
+ else if (typeof toolRef === 'object' && 'id' in toolRef && toolRef.id) {
776
+ // Inline tool definition
777
+ availableTools.set(toolRef.id, toolRef);
778
+ }
779
+ }
780
+ }
781
+ }
782
+ // Convert to the format expected by AI providers
783
+ return Array.from(availableTools.values()).map((tool) => ({
784
+ id: tool.id,
785
+ name: tool.name || tool.id,
786
+ description: tool.description,
787
+ parameters: tool.parameters,
788
+ }));
789
+ }
397
790
  /**
398
791
  * Unified streaming response generation
399
792
  * @private
400
793
  */
401
794
  async *generateUnifiedStreamingResponse(responseContext) {
402
- const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete } = responseContext;
795
+ const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete, batchSteps, batchStoppedReason, } = responseContext;
403
796
  const session = initialSession;
404
797
  // Get last user message (needed for both route and completion handling)
405
798
  // Convert HistoryItem[] to Event[] for internal processing
406
799
  const historyEvents = (0, utils_1.historyToEvents)(history);
407
800
  const lastMessageText = (0, utils_1.getLastMessageFromHistory)(historyEvents);
408
801
  if (selectedRoute && !isRouteComplete) {
409
- // Handle normal route processing with streaming
410
- yield* this.processRouteStreamingResponse({
411
- selectedRoute,
412
- selectedStep,
413
- responseDirectives,
414
- session,
415
- history,
416
- context: effectiveContext,
417
- lastMessageText,
418
- historyEvents,
419
- });
802
+ // Check if we have batch steps to execute
803
+ if (batchSteps && batchSteps.length > 0) {
804
+ // BATCH EXECUTION: Execute multiple steps with streaming
805
+ // Note: For streaming, we still use batch execution but stream the response
806
+ utils_1.logger.debug(`[ResponseModal] Streaming batch execution for ${batchSteps.length} steps`);
807
+ yield* this.streamBatchResponse({
808
+ selectedRoute,
809
+ batchSteps,
810
+ responseDirectives,
811
+ session,
812
+ history,
813
+ context: effectiveContext,
814
+ historyEvents,
815
+ batchStoppedReason,
816
+ });
817
+ }
818
+ else {
819
+ // SINGLE STEP EXECUTION: Fall back to single-step streaming
820
+ yield* this.processRouteStreamingResponse({
821
+ selectedRoute,
822
+ selectedStep,
823
+ responseDirectives,
824
+ session,
825
+ history,
826
+ context: effectiveContext,
827
+ lastMessageText,
828
+ historyEvents,
829
+ });
830
+ }
420
831
  }
421
832
  else if (isRouteComplete && selectedRoute) {
422
833
  // Handle route completion streaming
@@ -437,6 +848,114 @@ class ResponseModal {
437
848
  });
438
849
  }
439
850
  }
851
+ /**
852
+ * Stream a batch response with multiple steps
853
+ *
854
+ * Similar to executeBatchResponse but streams the LLM response.
855
+ *
856
+ * @private
857
+ */
858
+ async *streamBatchResponse(params) {
859
+ const { selectedRoute, batchSteps, context, historyEvents, batchStoppedReason, signal } = params;
860
+ let session = params.session;
861
+ // Create hook executor function
862
+ const executeHook = async (hook, hookContext, data, step) => {
863
+ const route = selectedRoute;
864
+ const stepInstance = step?.id ? route.getStep(step.id) : undefined;
865
+ await this.executePrepareFinalize(hook, hookContext, data, route, stepInstance);
866
+ };
867
+ // PHASE 1: Execute all prepare hooks
868
+ const prepareResult = await this.batchExecutor.executePrepareHooks({
869
+ steps: batchSteps,
870
+ context,
871
+ data: session.data,
872
+ executeHook,
873
+ });
874
+ if (!prepareResult.success) {
875
+ // Yield error chunk
876
+ yield {
877
+ delta: "",
878
+ accumulated: "",
879
+ done: true,
880
+ session,
881
+ error: new ResponseGenerationError(`Prepare hook failed: ${prepareResult.error?.message}`, { phase: 'prepare_hooks' }),
882
+ };
883
+ return;
884
+ }
885
+ // PHASE 2: Build combined prompt
886
+ const batchPromptResult = await this.batchPromptBuilder.buildBatchPrompt({
887
+ steps: batchSteps,
888
+ route: selectedRoute,
889
+ history: historyEvents,
890
+ context,
891
+ session,
892
+ agentOptions: this.agent.getAgentOptions(),
893
+ });
894
+ const responseSchema = this.buildBatchResponseSchema(batchPromptResult.collectFields);
895
+ const availableTools = this.collectBatchAvailableTools(selectedRoute, batchSteps);
896
+ // PHASE 3: Stream LLM response
897
+ const agentOptions = this.agent.getAgentOptions();
898
+ const stream = agentOptions.provider.generateMessageStream({
899
+ prompt: batchPromptResult.prompt,
900
+ history: historyEvents,
901
+ context,
902
+ tools: availableTools,
903
+ signal,
904
+ parameters: responseSchema ? { jsonSchema: responseSchema, schemaName: "batch_stream_response" } : undefined,
905
+ });
906
+ // Build executed steps list
907
+ const executedSteps = batchSteps
908
+ .filter(step => step.id)
909
+ .map(step => ({
910
+ id: step.id,
911
+ routeId: selectedRoute.id,
912
+ }));
913
+ // Stream chunks
914
+ for await (const chunk of stream) {
915
+ // On final chunk, collect data and execute finalize hooks
916
+ if (chunk.done) {
917
+ // Collect data from response
918
+ if (chunk.structured) {
919
+ const collectResult = this.batchExecutor.collectBatchData({
920
+ steps: batchSteps,
921
+ llmResponse: chunk.structured,
922
+ session,
923
+ schema: this.agent.getSchema(),
924
+ });
925
+ session = collectResult.session;
926
+ if (collectResult.collectedData && Object.keys(collectResult.collectedData).length > 0) {
927
+ await this.agent.updateCollectedData(collectResult.collectedData);
928
+ }
929
+ }
930
+ // Update session to final step position
931
+ const lastStep = batchSteps[batchSteps.length - 1];
932
+ if (lastStep?.id) {
933
+ session = (0, utils_1.enterStep)(session, lastStep.id, lastStep.description);
934
+ }
935
+ // Execute finalize hooks
936
+ await this.batchExecutor.executeFinalizeHooks({
937
+ steps: batchSteps,
938
+ context,
939
+ data: session.data,
940
+ executeHook,
941
+ });
942
+ // Finalize session
943
+ await this.finalizeSession(session, context);
944
+ }
945
+ yield {
946
+ delta: chunk.delta,
947
+ accumulated: chunk.accumulated,
948
+ done: chunk.done,
949
+ session,
950
+ toolCalls: chunk.structured?.toolCalls,
951
+ isRouteComplete: false,
952
+ executedSteps: chunk.done ? executedSteps : undefined,
953
+ stoppedReason: chunk.done ? batchStoppedReason : undefined,
954
+ metadata: chunk.metadata,
955
+ structured: chunk.structured,
956
+ };
957
+ }
958
+ }
440
959
  /**
441
960
  * Execute prepare function for current step if available
442
961
  * @private
@@ -482,12 +1001,20 @@ class ResponseModal {
482
1001
  nextStep = selectedStep;
483
1002
  }
484
1003
  else {
485
- // New route or no step selected - get initial step or first valid step
1004
+ // Determine current step from session if we're already in this route
1005
+ const isInSameRoute = session.currentRoute?.id === selectedRoute.id;
1006
+ const currentStep = isInSameRoute && session.currentStep
1007
+ ? selectedRoute.getStep(session.currentStep.id)
1008
+ : undefined;
1009
+ utils_1.logger.debug(`[ResponseModal] Step determination: route match=${isInSameRoute}, currentRoute=${session.currentRoute?.id}, selectedRoute=${selectedRoute.id}, currentStep=${currentStep?.id || 'none'}`);
1010
+ // Get candidate steps based on current position in the route
486
1011
  const routingEngine = this.agent.getRoutingEngine();
487
- const candidates = routingEngine.getCandidateSteps(selectedRoute, undefined, session.data || {});
1012
+ const candidates = await routingEngine.getCandidateStepsWithConditions(selectedRoute, currentStep, // Pass current step instead of undefined to maintain progression
1013
+ (0, template_1.createTemplateContext)({ data: session.data, session, context }));
1014
+ utils_1.logger.debug(`[ResponseModal] Found ${candidates.length} candidate steps${currentStep ? ' from current step ' + currentStep.id : ' (new route entry)'}`);
488
1015
  if (candidates.length > 0) {
489
1016
  nextStep = candidates[0].step;
490
- utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id} for new route`);
1017
+ utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new route'}`);
491
1018
  }
492
1019
  else {
493
1020
  // Fallback to initial step even if it should be skipped
@@ -530,6 +1057,14 @@ class ResponseModal {
530
1057
  });
531
1058
  let message = result.structured?.message || result.message;
532
1059
  let toolCalls = result.structured?.toolCalls;
1060
+ // Debug: Log initial AI response
1061
+ utils_1.logger.debug(`[ResponseModal] Initial AI response:`, {
1062
+ hasMessage: !!message,
1063
+ messageLength: message?.length || 0,
1064
+ hasToolCalls: !!toolCalls,
1065
+ toolCallsCount: toolCalls?.length || 0,
1066
+ toolNames: toolCalls?.map(tc => tc.toolName) || [],
1067
+ });
533
1068
  // Execute tools with unified loop handling
534
1069
  const toolResult = await this.executeUnifiedToolLoop({
535
1070
  toolCalls,
@@ -564,11 +1099,17 @@ class ResponseModal {
564
1099
  nextStep = selectedStep;
565
1100
  }
566
1101
  else {
1102
+ // Determine current step from session if we're already in this route
1103
+ const currentStep = session.currentRoute?.id === selectedRoute.id && session.currentStep
1104
+ ? selectedRoute.getStep(session.currentStep.id)
1105
+ : undefined;
1106
+ // Get candidate steps based on current position in the route
567
1107
  const routingEngine = this.agent.getRoutingEngine();
568
- const candidates = routingEngine.getCandidateSteps(selectedRoute, undefined, session.data || {});
1108
+ const candidates = await routingEngine.getCandidateStepsWithConditions(selectedRoute, currentStep, // Pass current step instead of undefined to maintain progression
1109
+ (0, template_1.createTemplateContext)({ data: session.data, session, context }));
569
1110
  if (candidates.length > 0) {
570
1111
  nextStep = candidates[0].step;
571
- utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id} for new route`);
1112
+ utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new route'}`);
572
1113
  }
573
1114
  else {
574
1115
  nextStep = selectedRoute.initialStep;
@@ -641,6 +1182,10 @@ class ResponseModal {
641
1182
  if (chunk.done) {
642
1183
  await this.finalizeSession(session, context);
643
1184
  }
1185
+ // Response structure completeness (Requirement 8.1, 8.2, 8.3)
1186
+ // - executedSteps: single step executed in this response
1187
+ // - stoppedReason: 'needs_input' for single-step execution (waiting for user input)
1188
+ // - session.currentStep: reflects the executed step
644
1189
  yield {
645
1190
  delta: chunk.delta,
646
1191
  accumulated: chunk.accumulated,
@@ -648,6 +1193,8 @@ class ResponseModal {
648
1193
  session,
649
1194
  toolCalls,
650
1195
  isRouteComplete: false,
1196
+ executedSteps: chunk.done ? [{ id: nextStep.id, routeId: selectedRoute.id }] : undefined,
1197
+ stoppedReason: chunk.done ? 'needs_input' : undefined,
651
1198
  metadata: chunk.metadata,
652
1199
  structured: chunk.structured,
653
1200
  };
@@ -666,7 +1213,7 @@ class ResponseModal {
666
1213
  const historyEvents = (0, utils_1.historyToEvents)(history);
667
1214
  // Execute initial dynamic tool calls
668
1215
  if (toolCalls && toolCalls.length > 0) {
669
- utils_1.logger.debug(`[ResponseModal] Executing ${toolCalls.length} dynamic tool calls`);
1216
+ utils_1.logger.debug(`[ResponseModal] Executing ${toolCalls.length} dynamic tool calls:`, toolCalls.map(tc => tc.toolName));
670
1217
  for (const toolCall of toolCalls) {
671
1218
  const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
672
1219
  if (!tool) {
@@ -736,7 +1283,7 @@ class ResponseModal {
736
1283
  let finalMessage;
737
1284
  while (hasToolCalls && toolLoopCount < MAX_TOOL_LOOPS) {
738
1285
  toolLoopCount++;
739
- utils_1.logger.debug(`[ResponseModal] Starting tool loop ${toolLoopCount}/${MAX_TOOL_LOOPS}`);
1286
+ utils_1.logger.debug(`[ResponseModal] Starting tool loop ${toolLoopCount}/${MAX_TOOL_LOOPS} with ${toolCalls?.length || 0} tool calls`);
740
1287
  // Create tool result events with proper Event format structure
741
1288
  const toolResultEvents = [];
742
1289
  for (const toolCall of toolCalls || []) {
@@ -765,12 +1312,19 @@ class ResponseModal {
765
1312
  // Create updated history with tool results (combine Event arrays)
766
1313
  const updatedHistoryEvents = [...historyEvents, ...toolResultEvents];
767
1314
  // Make follow-up AI call to see if more tools are needed
1315
+ // After first iteration, don't provide tools to force a text response
768
1316
  const agentOptions = this.agent.getAgentOptions();
1317
+ const shouldProvideTools = toolLoopCount === 1;
1318
+ utils_1.logger.debug(`[ResponseModal] Making follow-up AI call (loop ${toolLoopCount}):`, {
1319
+ providingTools: shouldProvideTools,
1320
+ toolsCount: shouldProvideTools ? availableTools.length : 0,
1321
+ addingTextInstruction: toolLoopCount > 1,
1322
+ });
769
1323
  const followUpResult = await agentOptions.provider.generateMessage({
770
- prompt: responsePrompt,
1324
+ prompt: responsePrompt + (toolLoopCount > 1 ? "\n\nProvide a text response to the user based on the tool results." : ""),
771
1325
  history: updatedHistoryEvents, // Use Event[] for AI provider
772
1326
  context,
773
- tools: availableTools,
1327
+ tools: shouldProvideTools ? availableTools : [], // Only provide tools on first iteration
774
1328
  parameters: responseSchema ? {
775
1329
  jsonSchema: responseSchema,
776
1330
  schemaName: "tool_followup",
@@ -780,6 +1334,13 @@ class ResponseModal {
780
1334
  // Check if follow-up call has more tool calls
781
1335
  const followUpToolCalls = followUpResult.structured?.toolCalls;
782
1336
  hasToolCalls = followUpToolCalls && followUpToolCalls.length > 0;
1337
+ utils_1.logger.debug(`[ResponseModal] Follow-up AI response (loop ${toolLoopCount}):`, {
1338
+ hasMessage: !!followUpResult.message,
1339
+ messageLength: followUpResult.message?.length || 0,
1340
+ hasToolCalls,
1341
+ toolCallsCount: followUpToolCalls?.length || 0,
1342
+ toolNames: followUpToolCalls?.map(tc => tc.toolName) || [],
1343
+ });
783
1344
  if (hasToolCalls) {
784
1345
  utils_1.logger.debug(`[ResponseModal] Follow-up call produced ${followUpToolCalls.length} additional tool calls`);
785
1346
  // Execute the follow-up tool calls
@@ -853,6 +1414,12 @@ class ResponseModal {
853
1414
  if (toolLoopCount >= MAX_TOOL_LOOPS) {
854
1415
  utils_1.logger.warn(`[ResponseModal] Tool loop limit reached (${MAX_TOOL_LOOPS}), stopping`);
855
1416
  }
1417
+ utils_1.logger.debug(`[ResponseModal] Tool loop completed:`, {
1418
+ totalIterations: toolLoopCount,
1419
+ hasFinalMessage: !!finalMessage,
1420
+ finalMessageLength: finalMessage?.length || 0,
1421
+ finalToolCallsCount: toolCalls?.length || 0,
1422
+ });
856
1423
  return {
857
1424
  session,
858
1425
  finalToolCalls: toolCalls,
@@ -874,14 +1441,29 @@ class ResponseModal {
874
1441
  const { result, selectedRoute, nextStep, session } = params;
875
1442
  let updatedSession = session;
876
1443
  // Extract collected data from final response (only for route-based interactions)
877
- if (selectedRoute && result.structured && nextStep?.collect) {
1444
+ if (selectedRoute && result.structured) {
878
1445
  try {
879
1446
  const collectedData = {};
880
1447
  // AgentStructuredResponse extends Record<string, unknown>, so we can safely access properties
881
1448
  const structuredData = result.structured;
882
- for (const field of nextStep.collect) {
1449
+ // Collect ALL route fields (required + optional) from structured response
1450
+ const allRouteFields = new Set();
1451
+ // Add route required fields
1452
+ if (selectedRoute.requiredFields) {
1453
+ selectedRoute.requiredFields.forEach(field => allRouteFields.add(String(field)));
1454
+ }
1455
+ // Add route optional fields
1456
+ if (selectedRoute.optionalFields) {
1457
+ selectedRoute.optionalFields.forEach(field => allRouteFields.add(String(field)));
1458
+ }
1459
+ // Also include current step's collect fields (in case they're not in route fields)
1460
+ if (nextStep?.collect) {
1461
+ nextStep.collect.forEach(field => allRouteFields.add(String(field)));
1462
+ }
1463
+ // Extract all available fields from structured response
1464
+ for (const field of allRouteFields) {
883
1465
  const fieldKey = String(field);
884
- if (fieldKey in structuredData) {
1466
+ if (fieldKey in structuredData && structuredData[fieldKey] !== undefined && structuredData[fieldKey] !== null) {
885
1467
  collectedData[fieldKey] = structuredData[fieldKey];
886
1468
  }
887
1469
  }
@@ -944,34 +1526,60 @@ class ResponseModal {
944
1526
  requires: endStepSpec.requires,
945
1527
  prompt: endStepSpec.prompt || "Summarize what was accomplished and confirm completion based on the conversation history and collected data",
946
1528
  });
947
- // Build response schema for completion
948
- const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionStep, this.agent.getSchema());
949
- const templateContext = { context, session, history: historyEvents }; // Use Event[] for template context
950
- // Build completion response prompt
1529
+ // Build response schema for completion (message only, no data collection)
1530
+ const completionSchema = {
1531
+ type: "object",
1532
+ properties: {
1533
+ message: {
1534
+ type: "string",
1535
+ description: "Completion message confirming what was accomplished",
1536
+ },
1537
+ },
1538
+ required: ["message"],
1539
+ additionalProperties: false,
1540
+ };
1541
+ const templateContext = (0, template_1.createTemplateContext)({ context, session, history: historyEvents });
1542
+ // Build completion response prompt using ResponseEngine
1543
+ // Filter out conditional guidelines - only include always-active ones
1544
+ const alwaysActiveGuidelines = [
1545
+ ...this.agent.getGuidelines().filter(g => !g.condition),
1546
+ ...selectedRoute.getGuidelines().filter(g => !g.condition),
1547
+ ];
1548
+ let completitionPrompt = "Summarize what was accomplished and confirm completion";
1549
+ if (endStepSpec.prompt) {
1550
+ completitionPrompt = await (0, utils_1.render)(endStepSpec.prompt, templateContext);
1551
+ }
951
1552
  const completionPrompt = await this.responseEngine.buildResponsePrompt({
952
1553
  route: selectedRoute,
953
1554
  currentStep: completionStep,
954
1555
  rules: selectedRoute.getRules(),
955
1556
  prohibitions: selectedRoute.getProhibitions(),
956
- directives: undefined, // No directives for completion
957
- history: historyEvents, // Use Event[] for buildResponsePrompt
958
- lastMessage: lastMessageText, // Use string for buildResponsePrompt
1557
+ directives: [
1558
+ `Task completed: ${selectedRoute.title}`,
1559
+ `Collected data: ${JSON.stringify(session.data, null, 2)}`,
1560
+ "Do NOT ask for more information - the task is complete",
1561
+ completitionPrompt,
1562
+ ],
1563
+ history: historyEvents,
1564
+ lastMessage: lastMessageText,
959
1565
  agentOptions: this.agent.getAgentOptions(),
960
- combinedGuidelines: [...this.agent.getGuidelines(), ...selectedRoute.getGuidelines()],
1566
+ combinedGuidelines: alwaysActiveGuidelines, // Only non-conditional guidelines
961
1567
  combinedTerms: this.mergeTerms(this.agent.getTerms(), selectedRoute.getTerms()),
962
1568
  context,
963
1569
  session,
964
- agentSchema: this.agent.getSchema(),
1570
+ agentSchema: undefined, // No data collection schema for completion
965
1571
  });
966
1572
  // Generate completion message using AI provider
967
1573
  const agentOptions = this.agent.getAgentOptions();
1574
+ utils_1.logger.debug(`[ResponseModal] Calling AI provider for completion message...`);
968
1575
  const completionResult = await agentOptions.provider.generateMessage({
969
1576
  prompt: completionPrompt,
970
- history: historyEvents, // Use Event[] for AI provider
1577
+ history: historyEvents,
971
1578
  context,
972
1579
  signal,
973
- parameters: { jsonSchema: responseSchema, schemaName: "completion_message" },
1580
+ parameters: { jsonSchema: completionSchema, schemaName: "completion_message" },
974
1581
  });
1582
+ utils_1.logger.debug(`[ResponseModal] AI provider returned completion result`);
975
1583
  const message = completionResult.structured?.message || completionResult.message;
976
1584
  utils_1.logger.debug(`[ResponseModal] Generated completion message for route: ${selectedRoute.title}`);
977
1585
  // Check for onComplete transition
@@ -1014,7 +1622,7 @@ class ResponseModal {
1014
1622
  });
1015
1623
  // Build response schema for completion
1016
1624
  const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionStep, this.agent.getSchema());
1017
- const templateContext = { context, session, history: historyEvents }; // Use Event[] for template context
1625
+ const templateContext = (0, template_1.createTemplateContext)({ context, session, history: historyEvents }); // Use Event[] for template context
1018
1626
  // Build completion response prompt
1019
1627
  const completionPrompt = await this.responseEngine.buildResponsePrompt({
1020
1628
  route: selectedRoute,
@@ -1072,6 +1680,10 @@ class ResponseModal {
1072
1680
  if (chunk.done) {
1073
1681
  await this.finalizeSession(session, context);
1074
1682
  }
1683
+ // Response structure completeness (Requirement 8.1, 8.2, 8.3)
1684
+ // - executedSteps: empty for route completion (no new steps executed)
1685
+ // - stoppedReason: 'route_complete' for completed routes
1686
+ // - session.currentStep: set to END_ROUTE
1075
1687
  yield {
1076
1688
  delta: chunk.delta,
1077
1689
  accumulated: chunk.accumulated,
@@ -1079,6 +1691,8 @@ class ResponseModal {
1079
1691
  session,
1080
1692
  toolCalls: undefined,
1081
1693
  isRouteComplete: true,
1694
+ executedSteps: chunk.done ? [] : undefined,
1695
+ stoppedReason: chunk.done ? 'route_complete' : undefined,
1082
1696
  metadata: chunk.metadata,
1083
1697
  structured: chunk.structured,
1084
1698
  };
@@ -1153,6 +1767,10 @@ class ResponseModal {
1153
1767
  if (chunk.done) {
1154
1768
  await this.finalizeSession(session, context);
1155
1769
  }
1770
+ // Response structure completeness (Requirement 8.1, 8.2, 8.3)
1771
+ // - executedSteps: empty for fallback (no route/step execution)
1772
+ // - stoppedReason: undefined for fallback (no route context)
1773
+ // - session.currentStep: unchanged (no step progression)
1156
1774
  yield {
1157
1775
  delta: chunk.delta,
1158
1776
  accumulated: chunk.accumulated,
@@ -1160,6 +1778,8 @@ class ResponseModal {
1160
1778
  session,
1161
1779
  toolCalls: undefined,
1162
1780
  isRouteComplete: false,
1781
+ executedSteps: chunk.done ? [] : undefined,
1782
+ stoppedReason: undefined,
1163
1783
  metadata: chunk.metadata,
1164
1784
  structured: chunk.structured,
1165
1785
  };