@falai/agent 3.4.4 → 4.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (847) hide show
  1. package/README.md +41 -34
  2. package/dist/cjs/core/Agent.d.ts +22 -378
  3. package/dist/cjs/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/core/Agent.js +104 -1178
  5. package/dist/cjs/core/Agent.js.map +1 -1
  6. package/dist/cjs/core/CompactionEngine.d.ts.map +1 -1
  7. package/dist/cjs/core/CompactionEngine.js +5 -3
  8. package/dist/cjs/core/CompactionEngine.js.map +1 -1
  9. package/dist/cjs/core/FlowSpec.d.ts +136 -0
  10. package/dist/cjs/core/FlowSpec.d.ts.map +1 -0
  11. package/dist/cjs/core/FlowSpec.js +522 -0
  12. package/dist/cjs/core/FlowSpec.js.map +1 -0
  13. package/dist/cjs/core/Migrate.d.ts +38 -0
  14. package/dist/cjs/core/Migrate.d.ts.map +1 -0
  15. package/dist/cjs/core/Migrate.js +270 -0
  16. package/dist/cjs/core/Migrate.js.map +1 -0
  17. package/dist/cjs/core/Prompt.d.ts +54 -0
  18. package/dist/cjs/core/Prompt.d.ts.map +1 -0
  19. package/dist/cjs/core/Prompt.js +143 -0
  20. package/dist/cjs/core/Prompt.js.map +1 -0
  21. package/dist/cjs/core/Runner.d.ts +160 -0
  22. package/dist/cjs/core/Runner.d.ts.map +1 -0
  23. package/dist/cjs/core/Runner.js +1131 -0
  24. package/dist/cjs/core/Runner.js.map +1 -0
  25. package/dist/cjs/core/Speak.d.ts +37 -0
  26. package/dist/cjs/core/Speak.d.ts.map +1 -0
  27. package/dist/cjs/core/Speak.js +364 -0
  28. package/dist/cjs/core/Speak.js.map +1 -0
  29. package/dist/cjs/core/Understand.d.ts +28 -0
  30. package/dist/cjs/core/Understand.d.ts.map +1 -0
  31. package/dist/cjs/core/Understand.js +353 -0
  32. package/dist/cjs/core/Understand.js.map +1 -0
  33. package/dist/cjs/core/contracts.d.ts +122 -0
  34. package/dist/cjs/core/contracts.d.ts.map +1 -0
  35. package/dist/cjs/core/contracts.js +11 -0
  36. package/dist/cjs/core/contracts.js.map +1 -0
  37. package/dist/cjs/core/falai.d.ts +57 -0
  38. package/dist/cjs/core/falai.d.ts.map +1 -0
  39. package/dist/cjs/core/falai.js +43 -0
  40. package/dist/cjs/core/falai.js.map +1 -0
  41. package/dist/cjs/core/predicate.d.ts +9 -0
  42. package/dist/cjs/core/predicate.d.ts.map +1 -0
  43. package/dist/cjs/core/predicate.js +58 -0
  44. package/dist/cjs/core/predicate.js.map +1 -0
  45. package/dist/cjs/index.d.ts +26 -31
  46. package/dist/cjs/index.d.ts.map +1 -1
  47. package/dist/cjs/index.js +46 -68
  48. package/dist/cjs/index.js.map +1 -1
  49. package/dist/cjs/persistence/MemoryStore.d.ts +15 -0
  50. package/dist/cjs/persistence/MemoryStore.d.ts.map +1 -0
  51. package/dist/cjs/persistence/MemoryStore.js +39 -0
  52. package/dist/cjs/persistence/MemoryStore.js.map +1 -0
  53. package/dist/cjs/persistence/MongoStore.d.ts +42 -0
  54. package/dist/cjs/persistence/MongoStore.d.ts.map +1 -0
  55. package/dist/cjs/persistence/MongoStore.js +60 -0
  56. package/dist/cjs/persistence/MongoStore.js.map +1 -0
  57. package/dist/cjs/persistence/OpenSearchStore.d.ts +86 -0
  58. package/dist/cjs/persistence/OpenSearchStore.d.ts.map +1 -0
  59. package/dist/cjs/persistence/OpenSearchStore.js +120 -0
  60. package/dist/cjs/persistence/OpenSearchStore.js.map +1 -0
  61. package/dist/cjs/persistence/PostgresStore.d.ts +41 -0
  62. package/dist/cjs/persistence/PostgresStore.d.ts.map +1 -0
  63. package/dist/cjs/persistence/PostgresStore.js +58 -0
  64. package/dist/cjs/persistence/PostgresStore.js.map +1 -0
  65. package/dist/cjs/persistence/PrismaStore.d.ts +65 -0
  66. package/dist/cjs/persistence/PrismaStore.d.ts.map +1 -0
  67. package/dist/cjs/persistence/PrismaStore.js +95 -0
  68. package/dist/cjs/persistence/PrismaStore.js.map +1 -0
  69. package/dist/cjs/persistence/RedisStore.d.ts +34 -0
  70. package/dist/cjs/persistence/RedisStore.d.ts.map +1 -0
  71. package/dist/cjs/persistence/RedisStore.js +61 -0
  72. package/dist/cjs/persistence/RedisStore.js.map +1 -0
  73. package/dist/cjs/persistence/SQLiteStore.d.ts +45 -0
  74. package/dist/cjs/persistence/SQLiteStore.d.ts.map +1 -0
  75. package/dist/cjs/persistence/SQLiteStore.js +74 -0
  76. package/dist/cjs/persistence/SQLiteStore.js.map +1 -0
  77. package/dist/cjs/persistence/sessionRow.d.ts +14 -0
  78. package/dist/cjs/persistence/sessionRow.d.ts.map +1 -0
  79. package/dist/cjs/persistence/sessionRow.js +50 -0
  80. package/dist/cjs/persistence/sessionRow.js.map +1 -0
  81. package/dist/cjs/providers/DeepSeekProvider.d.ts.map +1 -1
  82. package/dist/cjs/providers/DeepSeekProvider.js +8 -3
  83. package/dist/cjs/providers/DeepSeekProvider.js.map +1 -1
  84. package/dist/cjs/providers/GeminiProvider.d.ts +4 -3
  85. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  86. package/dist/cjs/providers/GeminiProvider.js +4 -3
  87. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  88. package/dist/cjs/providers/OpenAICompatibleProvider.d.ts +4 -0
  89. package/dist/cjs/providers/OpenAICompatibleProvider.d.ts.map +1 -1
  90. package/dist/cjs/providers/OpenAICompatibleProvider.js +2 -0
  91. package/dist/cjs/providers/OpenAICompatibleProvider.js.map +1 -1
  92. package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
  93. package/dist/cjs/providers/OpenRouterProvider.js +2 -4
  94. package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
  95. package/dist/cjs/providers/ProviderAdapter.d.ts +1 -1
  96. package/dist/cjs/providers/ProviderAdapter.d.ts.map +1 -1
  97. package/dist/cjs/providers/ProviderAdapter.js +33 -10
  98. package/dist/cjs/providers/ProviderAdapter.js.map +1 -1
  99. package/dist/cjs/types/agent.d.ts +153 -383
  100. package/dist/cjs/types/agent.d.ts.map +1 -1
  101. package/dist/cjs/types/agent.js +1 -1
  102. package/dist/cjs/types/ai.d.ts +32 -1
  103. package/dist/cjs/types/ai.d.ts.map +1 -1
  104. package/dist/cjs/types/compaction.d.ts +3 -1
  105. package/dist/cjs/types/compaction.d.ts.map +1 -1
  106. package/dist/cjs/types/errors.d.ts +9 -12
  107. package/dist/cjs/types/errors.d.ts.map +1 -1
  108. package/dist/cjs/types/errors.js +14 -17
  109. package/dist/cjs/types/errors.js.map +1 -1
  110. package/dist/cjs/types/flow.d.ts +265 -513
  111. package/dist/cjs/types/flow.d.ts.map +1 -1
  112. package/dist/cjs/types/flow.js +7 -1
  113. package/dist/cjs/types/flow.js.map +1 -1
  114. package/dist/cjs/types/history.d.ts +7 -18
  115. package/dist/cjs/types/history.d.ts.map +1 -1
  116. package/dist/cjs/types/history.js.map +1 -1
  117. package/dist/cjs/types/index.d.ts +9 -15
  118. package/dist/cjs/types/index.d.ts.map +1 -1
  119. package/dist/cjs/types/index.js +4 -14
  120. package/dist/cjs/types/index.js.map +1 -1
  121. package/dist/cjs/types/session.d.ts +94 -64
  122. package/dist/cjs/types/session.d.ts.map +1 -1
  123. package/dist/cjs/types/session.js +5 -1
  124. package/dist/cjs/types/session.js.map +1 -1
  125. package/dist/cjs/types/tool.d.ts +37 -207
  126. package/dist/cjs/types/tool.d.ts.map +1 -1
  127. package/dist/cjs/types/tool.js +5 -14
  128. package/dist/cjs/types/tool.js.map +1 -1
  129. package/dist/cjs/utils/clock.d.ts +28 -0
  130. package/dist/cjs/utils/clock.d.ts.map +1 -0
  131. package/dist/cjs/utils/clock.js +64 -0
  132. package/dist/cjs/utils/clock.js.map +1 -0
  133. package/dist/cjs/utils/duration.d.ts +11 -0
  134. package/dist/cjs/utils/duration.d.ts.map +1 -0
  135. package/dist/cjs/utils/duration.js +31 -0
  136. package/dist/cjs/utils/duration.js.map +1 -0
  137. package/dist/cjs/utils/history.d.ts +4 -1
  138. package/dist/cjs/utils/history.d.ts.map +1 -1
  139. package/dist/cjs/utils/history.js +2 -2
  140. package/dist/cjs/utils/history.js.map +1 -1
  141. package/dist/cjs/utils/index.d.ts +4 -10
  142. package/dist/cjs/utils/index.d.ts.map +1 -1
  143. package/dist/cjs/utils/index.js +14 -61
  144. package/dist/cjs/utils/index.js.map +1 -1
  145. package/dist/cjs/utils/json.d.ts +2 -0
  146. package/dist/cjs/utils/json.d.ts.map +1 -1
  147. package/dist/cjs/utils/json.js +5 -0
  148. package/dist/cjs/utils/json.js.map +1 -1
  149. package/dist/cjs/utils/outcomes.d.ts +48 -0
  150. package/dist/cjs/utils/outcomes.d.ts.map +1 -0
  151. package/dist/cjs/utils/outcomes.js +51 -0
  152. package/dist/cjs/utils/outcomes.js.map +1 -0
  153. package/dist/cjs/utils/schema.d.ts +50 -0
  154. package/dist/cjs/utils/schema.d.ts.map +1 -0
  155. package/dist/cjs/utils/schema.js +138 -0
  156. package/dist/cjs/utils/schema.js.map +1 -0
  157. package/dist/cjs/utils/streamingMessage.d.ts +3 -2
  158. package/dist/cjs/utils/streamingMessage.d.ts.map +1 -1
  159. package/dist/cjs/utils/streamingMessage.js +38 -4
  160. package/dist/cjs/utils/streamingMessage.js.map +1 -1
  161. package/dist/cjs/utils/template.d.ts +13 -149
  162. package/dist/cjs/utils/template.d.ts.map +1 -1
  163. package/dist/cjs/utils/template.js +31 -363
  164. package/dist/cjs/utils/template.js.map +1 -1
  165. package/dist/cjs/utils/usage.d.ts +19 -0
  166. package/dist/cjs/utils/usage.d.ts.map +1 -0
  167. package/dist/cjs/utils/usage.js +35 -0
  168. package/dist/cjs/utils/usage.js.map +1 -0
  169. package/dist/core/Agent.d.ts +22 -378
  170. package/dist/core/Agent.d.ts.map +1 -1
  171. package/dist/core/Agent.js +107 -1181
  172. package/dist/core/Agent.js.map +1 -1
  173. package/dist/core/CompactionEngine.d.ts.map +1 -1
  174. package/dist/core/CompactionEngine.js +5 -3
  175. package/dist/core/CompactionEngine.js.map +1 -1
  176. package/dist/core/FlowSpec.d.ts +136 -0
  177. package/dist/core/FlowSpec.d.ts.map +1 -0
  178. package/dist/core/FlowSpec.js +516 -0
  179. package/dist/core/FlowSpec.js.map +1 -0
  180. package/dist/core/Migrate.d.ts +38 -0
  181. package/dist/core/Migrate.d.ts.map +1 -0
  182. package/dist/core/Migrate.js +264 -0
  183. package/dist/core/Migrate.js.map +1 -0
  184. package/dist/core/Prompt.d.ts +54 -0
  185. package/dist/core/Prompt.d.ts.map +1 -0
  186. package/dist/core/Prompt.js +133 -0
  187. package/dist/core/Prompt.js.map +1 -0
  188. package/dist/core/Runner.d.ts +160 -0
  189. package/dist/core/Runner.d.ts.map +1 -0
  190. package/dist/core/Runner.js +1127 -0
  191. package/dist/core/Runner.js.map +1 -0
  192. package/dist/core/Speak.d.ts +37 -0
  193. package/dist/core/Speak.d.ts.map +1 -0
  194. package/dist/core/Speak.js +360 -0
  195. package/dist/core/Speak.js.map +1 -0
  196. package/dist/core/Understand.d.ts +28 -0
  197. package/dist/core/Understand.d.ts.map +1 -0
  198. package/dist/core/Understand.js +349 -0
  199. package/dist/core/Understand.js.map +1 -0
  200. package/dist/core/contracts.d.ts +122 -0
  201. package/dist/core/contracts.d.ts.map +1 -0
  202. package/dist/core/contracts.js +10 -0
  203. package/dist/core/contracts.js.map +1 -0
  204. package/dist/core/falai.d.ts +57 -0
  205. package/dist/core/falai.d.ts.map +1 -0
  206. package/dist/core/falai.js +40 -0
  207. package/dist/core/falai.js.map +1 -0
  208. package/dist/core/predicate.d.ts +9 -0
  209. package/dist/core/predicate.d.ts.map +1 -0
  210. package/dist/core/predicate.js +54 -0
  211. package/dist/core/predicate.js.map +1 -0
  212. package/dist/index.d.ts +26 -31
  213. package/dist/index.d.ts.map +1 -1
  214. package/dist/index.js +19 -24
  215. package/dist/index.js.map +1 -1
  216. package/dist/persistence/MemoryStore.d.ts +15 -0
  217. package/dist/persistence/MemoryStore.d.ts.map +1 -0
  218. package/dist/persistence/MemoryStore.js +35 -0
  219. package/dist/persistence/MemoryStore.js.map +1 -0
  220. package/dist/persistence/MongoStore.d.ts +42 -0
  221. package/dist/persistence/MongoStore.d.ts.map +1 -0
  222. package/dist/persistence/MongoStore.js +56 -0
  223. package/dist/persistence/MongoStore.js.map +1 -0
  224. package/dist/persistence/OpenSearchStore.d.ts +86 -0
  225. package/dist/persistence/OpenSearchStore.d.ts.map +1 -0
  226. package/dist/persistence/OpenSearchStore.js +116 -0
  227. package/dist/persistence/OpenSearchStore.js.map +1 -0
  228. package/dist/persistence/PostgresStore.d.ts +41 -0
  229. package/dist/persistence/PostgresStore.d.ts.map +1 -0
  230. package/dist/persistence/PostgresStore.js +54 -0
  231. package/dist/persistence/PostgresStore.js.map +1 -0
  232. package/dist/persistence/PrismaStore.d.ts +65 -0
  233. package/dist/persistence/PrismaStore.d.ts.map +1 -0
  234. package/dist/persistence/PrismaStore.js +91 -0
  235. package/dist/persistence/PrismaStore.js.map +1 -0
  236. package/dist/persistence/RedisStore.d.ts +34 -0
  237. package/dist/persistence/RedisStore.d.ts.map +1 -0
  238. package/dist/persistence/RedisStore.js +57 -0
  239. package/dist/persistence/RedisStore.js.map +1 -0
  240. package/dist/persistence/SQLiteStore.d.ts +45 -0
  241. package/dist/persistence/SQLiteStore.d.ts.map +1 -0
  242. package/dist/persistence/SQLiteStore.js +70 -0
  243. package/dist/persistence/SQLiteStore.js.map +1 -0
  244. package/dist/persistence/sessionRow.d.ts +14 -0
  245. package/dist/persistence/sessionRow.d.ts.map +1 -0
  246. package/dist/persistence/sessionRow.js +45 -0
  247. package/dist/persistence/sessionRow.js.map +1 -0
  248. package/dist/providers/DeepSeekProvider.d.ts.map +1 -1
  249. package/dist/providers/DeepSeekProvider.js +8 -3
  250. package/dist/providers/DeepSeekProvider.js.map +1 -1
  251. package/dist/providers/GeminiProvider.d.ts +4 -3
  252. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  253. package/dist/providers/GeminiProvider.js +4 -3
  254. package/dist/providers/GeminiProvider.js.map +1 -1
  255. package/dist/providers/OpenAICompatibleProvider.d.ts +4 -0
  256. package/dist/providers/OpenAICompatibleProvider.d.ts.map +1 -1
  257. package/dist/providers/OpenAICompatibleProvider.js +2 -0
  258. package/dist/providers/OpenAICompatibleProvider.js.map +1 -1
  259. package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
  260. package/dist/providers/OpenRouterProvider.js +2 -4
  261. package/dist/providers/OpenRouterProvider.js.map +1 -1
  262. package/dist/providers/ProviderAdapter.d.ts +1 -1
  263. package/dist/providers/ProviderAdapter.d.ts.map +1 -1
  264. package/dist/providers/ProviderAdapter.js +34 -11
  265. package/dist/providers/ProviderAdapter.js.map +1 -1
  266. package/dist/types/agent.d.ts +153 -383
  267. package/dist/types/agent.d.ts.map +1 -1
  268. package/dist/types/agent.js +1 -1
  269. package/dist/types/ai.d.ts +32 -1
  270. package/dist/types/ai.d.ts.map +1 -1
  271. package/dist/types/compaction.d.ts +3 -1
  272. package/dist/types/compaction.d.ts.map +1 -1
  273. package/dist/types/errors.d.ts +9 -12
  274. package/dist/types/errors.d.ts.map +1 -1
  275. package/dist/types/errors.js +12 -15
  276. package/dist/types/errors.js.map +1 -1
  277. package/dist/types/flow.d.ts +265 -513
  278. package/dist/types/flow.d.ts.map +1 -1
  279. package/dist/types/flow.js +7 -1
  280. package/dist/types/flow.js.map +1 -1
  281. package/dist/types/history.d.ts +7 -18
  282. package/dist/types/history.d.ts.map +1 -1
  283. package/dist/types/history.js.map +1 -1
  284. package/dist/types/index.d.ts +9 -15
  285. package/dist/types/index.d.ts.map +1 -1
  286. package/dist/types/index.js +2 -7
  287. package/dist/types/index.js.map +1 -1
  288. package/dist/types/session.d.ts +94 -64
  289. package/dist/types/session.d.ts.map +1 -1
  290. package/dist/types/session.js +5 -1
  291. package/dist/types/session.js.map +1 -1
  292. package/dist/types/tool.d.ts +37 -207
  293. package/dist/types/tool.d.ts.map +1 -1
  294. package/dist/types/tool.js +6 -13
  295. package/dist/types/tool.js.map +1 -1
  296. package/dist/utils/clock.d.ts +28 -0
  297. package/dist/utils/clock.d.ts.map +1 -0
  298. package/dist/utils/clock.js +59 -0
  299. package/dist/utils/clock.js.map +1 -0
  300. package/dist/utils/duration.d.ts +11 -0
  301. package/dist/utils/duration.d.ts.map +1 -0
  302. package/dist/utils/duration.js +26 -0
  303. package/dist/utils/duration.js.map +1 -0
  304. package/dist/utils/history.d.ts +4 -1
  305. package/dist/utils/history.d.ts.map +1 -1
  306. package/dist/utils/history.js +2 -2
  307. package/dist/utils/history.js.map +1 -1
  308. package/dist/utils/index.d.ts +4 -10
  309. package/dist/utils/index.d.ts.map +1 -1
  310. package/dist/utils/index.js +4 -21
  311. package/dist/utils/index.js.map +1 -1
  312. package/dist/utils/json.d.ts +2 -0
  313. package/dist/utils/json.d.ts.map +1 -1
  314. package/dist/utils/json.js +4 -0
  315. package/dist/utils/json.js.map +1 -1
  316. package/dist/utils/outcomes.d.ts +48 -0
  317. package/dist/utils/outcomes.d.ts.map +1 -0
  318. package/dist/utils/outcomes.js +48 -0
  319. package/dist/utils/outcomes.js.map +1 -0
  320. package/dist/utils/schema.d.ts +50 -0
  321. package/dist/utils/schema.d.ts.map +1 -0
  322. package/dist/utils/schema.js +129 -0
  323. package/dist/utils/schema.js.map +1 -0
  324. package/dist/utils/streamingMessage.d.ts +3 -2
  325. package/dist/utils/streamingMessage.d.ts.map +1 -1
  326. package/dist/utils/streamingMessage.js +38 -4
  327. package/dist/utils/streamingMessage.js.map +1 -1
  328. package/dist/utils/template.d.ts +13 -149
  329. package/dist/utils/template.d.ts.map +1 -1
  330. package/dist/utils/template.js +28 -355
  331. package/dist/utils/template.js.map +1 -1
  332. package/dist/utils/usage.d.ts +19 -0
  333. package/dist/utils/usage.d.ts.map +1 -0
  334. package/dist/utils/usage.js +31 -0
  335. package/dist/utils/usage.js.map +1 -0
  336. package/docs/README.md +37 -19
  337. package/docs/concepts/architecture.md +117 -239
  338. package/docs/concepts/collection.md +170 -0
  339. package/docs/concepts/pipeline.md +132 -378
  340. package/docs/concepts/runs-and-waits.md +192 -0
  341. package/docs/guides/actions-and-events.md +276 -0
  342. package/docs/guides/branching.md +119 -208
  343. package/docs/guides/compaction.md +63 -158
  344. package/docs/guides/conditions.md +164 -128
  345. package/docs/guides/error-handling.md +168 -164
  346. package/docs/guides/flow-control.md +210 -349
  347. package/docs/guides/flows-from-json.md +224 -0
  348. package/docs/guides/instructions.md +125 -161
  349. package/docs/guides/persistence.md +182 -206
  350. package/docs/guides/streaming.md +50 -114
  351. package/docs/guides/testing.md +284 -0
  352. package/docs/guides/triggers.md +401 -0
  353. package/docs/migration/README.md +8 -15
  354. package/docs/migration/v1-to-v2.md +1 -1
  355. package/docs/migration/v2-3-to-v2-4.md +2 -2
  356. package/docs/migration/v2-6-to-v2-7.md +4 -4
  357. package/docs/migration/v3-to-v4.md +452 -0
  358. package/docs/reference/actions-events-conditions.md +396 -0
  359. package/docs/reference/agent.md +244 -0
  360. package/docs/reference/branches.md +75 -203
  361. package/docs/reference/errors.md +188 -144
  362. package/docs/reference/fields.md +125 -0
  363. package/docs/reference/flow-spec.md +248 -0
  364. package/docs/reference/flow.md +104 -192
  365. package/docs/reference/instruction.md +83 -137
  366. package/docs/reference/outcomes.md +273 -0
  367. package/docs/reference/providers.md +525 -302
  368. package/docs/reference/session.md +210 -0
  369. package/docs/reference/step.md +194 -312
  370. package/docs/reference/stores.md +496 -0
  371. package/docs/reference/tool.md +162 -231
  372. package/docs/reference/trigger.md +180 -0
  373. package/docs/rfc/v4-one-flow.md +477 -0
  374. package/docs/start/01-install.md +59 -44
  375. package/docs/start/02-first-agent.md +97 -147
  376. package/docs/start/03-collect-data.md +78 -183
  377. package/docs/start/04-add-tools.md +159 -227
  378. package/docs/start/05-go-to-production.md +167 -164
  379. package/examples/01-quickstart.ts +26 -16
  380. package/examples/02-fields.ts +75 -0
  381. package/examples/03-tools.ts +79 -119
  382. package/examples/04-instructions.ts +60 -87
  383. package/examples/05-branches.ts +78 -0
  384. package/examples/06-triggers-and-waits.ts +148 -0
  385. package/examples/07-streaming.ts +34 -60
  386. package/examples/08-store-and-migration.ts +97 -0
  387. package/examples/09-flows-from-json.ts +107 -0
  388. package/package.json +9 -6
  389. package/src/core/Agent.ts +116 -1512
  390. package/src/core/CompactionEngine.ts +7 -4
  391. package/src/core/FlowSpec.ts +712 -0
  392. package/src/core/Migrate.ts +256 -0
  393. package/src/core/Prompt.ts +156 -0
  394. package/src/core/Runner.ts +1181 -0
  395. package/src/core/Speak.ts +451 -0
  396. package/src/core/Understand.ts +422 -0
  397. package/src/core/contracts.ts +111 -0
  398. package/src/core/falai.ts +86 -0
  399. package/src/core/predicate.ts +56 -0
  400. package/src/index.ts +119 -147
  401. package/src/persistence/MemoryStore.ts +37 -0
  402. package/src/persistence/MongoStore.ts +89 -0
  403. package/src/persistence/OpenSearchStore.ts +153 -0
  404. package/src/persistence/PostgresStore.ts +89 -0
  405. package/src/persistence/PrismaStore.ts +127 -0
  406. package/src/persistence/RedisStore.ts +90 -0
  407. package/src/persistence/SQLiteStore.ts +103 -0
  408. package/src/persistence/sessionRow.ts +45 -0
  409. package/src/providers/DeepSeekProvider.ts +8 -3
  410. package/src/providers/GeminiProvider.ts +4 -3
  411. package/src/providers/OpenAICompatibleProvider.ts +6 -0
  412. package/src/providers/OpenRouterProvider.ts +2 -4
  413. package/src/providers/ProviderAdapter.ts +36 -8
  414. package/src/types/agent.ts +124 -397
  415. package/src/types/ai.ts +33 -1
  416. package/src/types/compaction.ts +3 -1
  417. package/src/types/errors.ts +13 -16
  418. package/src/types/flow.ts +249 -550
  419. package/src/types/history.ts +7 -20
  420. package/src/types/index.ts +87 -139
  421. package/src/types/session.ts +135 -70
  422. package/src/types/tool.ts +42 -267
  423. package/src/utils/clock.ts +70 -0
  424. package/src/utils/duration.ts +33 -0
  425. package/src/utils/history.ts +3 -2
  426. package/src/utils/index.ts +8 -66
  427. package/src/utils/json.ts +5 -0
  428. package/src/utils/outcomes.ts +56 -0
  429. package/src/utils/schema.ts +145 -0
  430. package/src/utils/streamingMessage.ts +34 -4
  431. package/src/utils/template.ts +32 -423
  432. package/src/utils/usage.ts +37 -0
  433. package/dist/adapters/MemoryAdapter.d.ts +0 -47
  434. package/dist/adapters/MemoryAdapter.d.ts.map +0 -1
  435. package/dist/adapters/MemoryAdapter.js +0 -204
  436. package/dist/adapters/MemoryAdapter.js.map +0 -1
  437. package/dist/adapters/MongoAdapter.d.ts +0 -97
  438. package/dist/adapters/MongoAdapter.d.ts.map +0 -1
  439. package/dist/adapters/MongoAdapter.js +0 -196
  440. package/dist/adapters/MongoAdapter.js.map +0 -1
  441. package/dist/adapters/OpenSearchAdapter.d.ts +0 -169
  442. package/dist/adapters/OpenSearchAdapter.d.ts.map +0 -1
  443. package/dist/adapters/OpenSearchAdapter.js +0 -471
  444. package/dist/adapters/OpenSearchAdapter.js.map +0 -1
  445. package/dist/adapters/PostgreSQLAdapter.d.ts +0 -85
  446. package/dist/adapters/PostgreSQLAdapter.d.ts.map +0 -1
  447. package/dist/adapters/PostgreSQLAdapter.js +0 -308
  448. package/dist/adapters/PostgreSQLAdapter.js.map +0 -1
  449. package/dist/adapters/PrismaAdapter.d.ts +0 -115
  450. package/dist/adapters/PrismaAdapter.d.ts.map +0 -1
  451. package/dist/adapters/PrismaAdapter.js +0 -406
  452. package/dist/adapters/PrismaAdapter.js.map +0 -1
  453. package/dist/adapters/RedisAdapter.d.ts +0 -72
  454. package/dist/adapters/RedisAdapter.d.ts.map +0 -1
  455. package/dist/adapters/RedisAdapter.js +0 -286
  456. package/dist/adapters/RedisAdapter.js.map +0 -1
  457. package/dist/adapters/SQLiteAdapter.d.ts +0 -86
  458. package/dist/adapters/SQLiteAdapter.d.ts.map +0 -1
  459. package/dist/adapters/SQLiteAdapter.js +0 -337
  460. package/dist/adapters/SQLiteAdapter.js.map +0 -1
  461. package/dist/adapters/index.d.ts +0 -17
  462. package/dist/adapters/index.d.ts.map +0 -1
  463. package/dist/adapters/index.js +0 -11
  464. package/dist/adapters/index.js.map +0 -1
  465. package/dist/adapters/sessionRow.d.ts +0 -22
  466. package/dist/adapters/sessionRow.d.ts.map +0 -1
  467. package/dist/adapters/sessionRow.js +0 -48
  468. package/dist/adapters/sessionRow.js.map +0 -1
  469. package/dist/cjs/adapters/MemoryAdapter.d.ts +0 -47
  470. package/dist/cjs/adapters/MemoryAdapter.d.ts.map +0 -1
  471. package/dist/cjs/adapters/MemoryAdapter.js +0 -208
  472. package/dist/cjs/adapters/MemoryAdapter.js.map +0 -1
  473. package/dist/cjs/adapters/MongoAdapter.d.ts +0 -97
  474. package/dist/cjs/adapters/MongoAdapter.d.ts.map +0 -1
  475. package/dist/cjs/adapters/MongoAdapter.js +0 -200
  476. package/dist/cjs/adapters/MongoAdapter.js.map +0 -1
  477. package/dist/cjs/adapters/OpenSearchAdapter.d.ts +0 -169
  478. package/dist/cjs/adapters/OpenSearchAdapter.d.ts.map +0 -1
  479. package/dist/cjs/adapters/OpenSearchAdapter.js +0 -475
  480. package/dist/cjs/adapters/OpenSearchAdapter.js.map +0 -1
  481. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts +0 -85
  482. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +0 -1
  483. package/dist/cjs/adapters/PostgreSQLAdapter.js +0 -312
  484. package/dist/cjs/adapters/PostgreSQLAdapter.js.map +0 -1
  485. package/dist/cjs/adapters/PrismaAdapter.d.ts +0 -115
  486. package/dist/cjs/adapters/PrismaAdapter.d.ts.map +0 -1
  487. package/dist/cjs/adapters/PrismaAdapter.js +0 -410
  488. package/dist/cjs/adapters/PrismaAdapter.js.map +0 -1
  489. package/dist/cjs/adapters/RedisAdapter.d.ts +0 -72
  490. package/dist/cjs/adapters/RedisAdapter.d.ts.map +0 -1
  491. package/dist/cjs/adapters/RedisAdapter.js +0 -290
  492. package/dist/cjs/adapters/RedisAdapter.js.map +0 -1
  493. package/dist/cjs/adapters/SQLiteAdapter.d.ts +0 -86
  494. package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +0 -1
  495. package/dist/cjs/adapters/SQLiteAdapter.js +0 -341
  496. package/dist/cjs/adapters/SQLiteAdapter.js.map +0 -1
  497. package/dist/cjs/adapters/index.d.ts +0 -17
  498. package/dist/cjs/adapters/index.d.ts.map +0 -1
  499. package/dist/cjs/adapters/index.js +0 -21
  500. package/dist/cjs/adapters/index.js.map +0 -1
  501. package/dist/cjs/adapters/sessionRow.d.ts +0 -22
  502. package/dist/cjs/adapters/sessionRow.d.ts.map +0 -1
  503. package/dist/cjs/adapters/sessionRow.js +0 -52
  504. package/dist/cjs/adapters/sessionRow.js.map +0 -1
  505. package/dist/cjs/constants/index.d.ts +0 -1
  506. package/dist/cjs/constants/index.d.ts.map +0 -1
  507. package/dist/cjs/constants/index.js +0 -4
  508. package/dist/cjs/constants/index.js.map +0 -1
  509. package/dist/cjs/core/AutoChainExecutor.d.ts +0 -97
  510. package/dist/cjs/core/AutoChainExecutor.d.ts.map +0 -1
  511. package/dist/cjs/core/AutoChainExecutor.js +0 -288
  512. package/dist/cjs/core/AutoChainExecutor.js.map +0 -1
  513. package/dist/cjs/core/BranchEvaluator.d.ts +0 -55
  514. package/dist/cjs/core/BranchEvaluator.d.ts.map +0 -1
  515. package/dist/cjs/core/BranchEvaluator.js +0 -125
  516. package/dist/cjs/core/BranchEvaluator.js.map +0 -1
  517. package/dist/cjs/core/DirectiveChainTracker.d.ts +0 -49
  518. package/dist/cjs/core/DirectiveChainTracker.d.ts.map +0 -1
  519. package/dist/cjs/core/DirectiveChainTracker.js +0 -121
  520. package/dist/cjs/core/DirectiveChainTracker.js.map +0 -1
  521. package/dist/cjs/core/Events.d.ts +0 -26
  522. package/dist/cjs/core/Events.d.ts.map +0 -1
  523. package/dist/cjs/core/Events.js +0 -144
  524. package/dist/cjs/core/Events.js.map +0 -1
  525. package/dist/cjs/core/Flow.d.ts +0 -183
  526. package/dist/cjs/core/Flow.d.ts.map +0 -1
  527. package/dist/cjs/core/Flow.js +0 -551
  528. package/dist/cjs/core/Flow.js.map +0 -1
  529. package/dist/cjs/core/FlowRouter.d.ts +0 -183
  530. package/dist/cjs/core/FlowRouter.d.ts.map +0 -1
  531. package/dist/cjs/core/FlowRouter.js +0 -1047
  532. package/dist/cjs/core/FlowRouter.js.map +0 -1
  533. package/dist/cjs/core/PersistenceManager.d.ts +0 -114
  534. package/dist/cjs/core/PersistenceManager.d.ts.map +0 -1
  535. package/dist/cjs/core/PersistenceManager.js +0 -336
  536. package/dist/cjs/core/PersistenceManager.js.map +0 -1
  537. package/dist/cjs/core/PromptComposer.d.ts +0 -47
  538. package/dist/cjs/core/PromptComposer.d.ts.map +0 -1
  539. package/dist/cjs/core/PromptComposer.js +0 -397
  540. package/dist/cjs/core/PromptComposer.js.map +0 -1
  541. package/dist/cjs/core/PromptSectionCache.d.ts +0 -48
  542. package/dist/cjs/core/PromptSectionCache.d.ts.map +0 -1
  543. package/dist/cjs/core/PromptSectionCache.js +0 -108
  544. package/dist/cjs/core/PromptSectionCache.js.map +0 -1
  545. package/dist/cjs/core/ResponseEngine.d.ts +0 -43
  546. package/dist/cjs/core/ResponseEngine.d.ts.map +0 -1
  547. package/dist/cjs/core/ResponseEngine.js +0 -235
  548. package/dist/cjs/core/ResponseEngine.js.map +0 -1
  549. package/dist/cjs/core/ResponseGenerationError.d.ts +0 -30
  550. package/dist/cjs/core/ResponseGenerationError.d.ts.map +0 -1
  551. package/dist/cjs/core/ResponseGenerationError.js +0 -35
  552. package/dist/cjs/core/ResponseGenerationError.js.map +0 -1
  553. package/dist/cjs/core/ResponseModal.d.ts +0 -305
  554. package/dist/cjs/core/ResponseModal.d.ts.map +0 -1
  555. package/dist/cjs/core/ResponseModal.js +0 -1414
  556. package/dist/cjs/core/ResponseModal.js.map +0 -1
  557. package/dist/cjs/core/ResponsePipeline.d.ts +0 -220
  558. package/dist/cjs/core/ResponsePipeline.d.ts.map +0 -1
  559. package/dist/cjs/core/ResponsePipeline.js +0 -1040
  560. package/dist/cjs/core/ResponsePipeline.js.map +0 -1
  561. package/dist/cjs/core/SessionFinalizer.d.ts +0 -34
  562. package/dist/cjs/core/SessionFinalizer.d.ts.map +0 -1
  563. package/dist/cjs/core/SessionFinalizer.js +0 -88
  564. package/dist/cjs/core/SessionFinalizer.js.map +0 -1
  565. package/dist/cjs/core/SessionManager.d.ts +0 -112
  566. package/dist/cjs/core/SessionManager.d.ts.map +0 -1
  567. package/dist/cjs/core/SessionManager.js +0 -308
  568. package/dist/cjs/core/SessionManager.js.map +0 -1
  569. package/dist/cjs/core/SignalCoordinator.d.ts +0 -103
  570. package/dist/cjs/core/SignalCoordinator.d.ts.map +0 -1
  571. package/dist/cjs/core/SignalCoordinator.js +0 -207
  572. package/dist/cjs/core/SignalCoordinator.js.map +0 -1
  573. package/dist/cjs/core/SignalEvaluator.d.ts +0 -86
  574. package/dist/cjs/core/SignalEvaluator.d.ts.map +0 -1
  575. package/dist/cjs/core/SignalEvaluator.js +0 -319
  576. package/dist/cjs/core/SignalEvaluator.js.map +0 -1
  577. package/dist/cjs/core/SignalProcessor.d.ts +0 -152
  578. package/dist/cjs/core/SignalProcessor.d.ts.map +0 -1
  579. package/dist/cjs/core/SignalProcessor.js +0 -505
  580. package/dist/cjs/core/SignalProcessor.js.map +0 -1
  581. package/dist/cjs/core/Step.d.ts +0 -184
  582. package/dist/cjs/core/Step.d.ts.map +0 -1
  583. package/dist/cjs/core/Step.js +0 -599
  584. package/dist/cjs/core/Step.js.map +0 -1
  585. package/dist/cjs/core/StepLifecycle.d.ts +0 -43
  586. package/dist/cjs/core/StepLifecycle.d.ts.map +0 -1
  587. package/dist/cjs/core/StepLifecycle.js +0 -180
  588. package/dist/cjs/core/StepLifecycle.js.map +0 -1
  589. package/dist/cjs/core/StreamingToolExecutor.d.ts +0 -142
  590. package/dist/cjs/core/StreamingToolExecutor.d.ts.map +0 -1
  591. package/dist/cjs/core/StreamingToolExecutor.js +0 -490
  592. package/dist/cjs/core/StreamingToolExecutor.js.map +0 -1
  593. package/dist/cjs/core/ToolLoopExecutor.d.ts +0 -133
  594. package/dist/cjs/core/ToolLoopExecutor.d.ts.map +0 -1
  595. package/dist/cjs/core/ToolLoopExecutor.js +0 -568
  596. package/dist/cjs/core/ToolLoopExecutor.js.map +0 -1
  597. package/dist/cjs/core/ToolManager.d.ts +0 -250
  598. package/dist/cjs/core/ToolManager.d.ts.map +0 -1
  599. package/dist/cjs/core/ToolManager.js +0 -1104
  600. package/dist/cjs/core/ToolManager.js.map +0 -1
  601. package/dist/cjs/core/createAgent.d.ts +0 -35
  602. package/dist/cjs/core/createAgent.d.ts.map +0 -1
  603. package/dist/cjs/core/createAgent.js +0 -39
  604. package/dist/cjs/core/createAgent.js.map +0 -1
  605. package/dist/cjs/core/flow-namespace.d.ts +0 -64
  606. package/dist/cjs/core/flow-namespace.d.ts.map +0 -1
  607. package/dist/cjs/core/flow-namespace.js +0 -182
  608. package/dist/cjs/core/flow-namespace.js.map +0 -1
  609. package/dist/cjs/core/toolGates.d.ts +0 -24
  610. package/dist/cjs/core/toolGates.d.ts.map +0 -1
  611. package/dist/cjs/core/toolGates.js +0 -52
  612. package/dist/cjs/core/toolGates.js.map +0 -1
  613. package/dist/cjs/types/persistence.d.ts +0 -254
  614. package/dist/cjs/types/persistence.d.ts.map +0 -1
  615. package/dist/cjs/types/persistence.js +0 -7
  616. package/dist/cjs/types/persistence.js.map +0 -1
  617. package/dist/cjs/types/prompt-cache.d.ts +0 -15
  618. package/dist/cjs/types/prompt-cache.d.ts.map +0 -1
  619. package/dist/cjs/types/prompt-cache.js +0 -6
  620. package/dist/cjs/types/prompt-cache.js.map +0 -1
  621. package/dist/cjs/types/signals.d.ts +0 -263
  622. package/dist/cjs/types/signals.d.ts.map +0 -1
  623. package/dist/cjs/types/signals.js +0 -11
  624. package/dist/cjs/types/signals.js.map +0 -1
  625. package/dist/cjs/types/template.d.ts +0 -84
  626. package/dist/cjs/types/template.d.ts.map +0 -1
  627. package/dist/cjs/types/template.js +0 -3
  628. package/dist/cjs/types/template.js.map +0 -1
  629. package/dist/cjs/utils/condition.d.ts +0 -63
  630. package/dist/cjs/utils/condition.d.ts.map +0 -1
  631. package/dist/cjs/utils/condition.js +0 -239
  632. package/dist/cjs/utils/condition.js.map +0 -1
  633. package/dist/cjs/utils/event.d.ts +0 -6
  634. package/dist/cjs/utils/event.d.ts.map +0 -1
  635. package/dist/cjs/utils/event.js +0 -20
  636. package/dist/cjs/utils/event.js.map +0 -1
  637. package/dist/cjs/utils/id.d.ts +0 -33
  638. package/dist/cjs/utils/id.d.ts.map +0 -1
  639. package/dist/cjs/utils/id.js +0 -84
  640. package/dist/cjs/utils/id.js.map +0 -1
  641. package/dist/cjs/utils/serialize.d.ts +0 -36
  642. package/dist/cjs/utils/serialize.d.ts.map +0 -1
  643. package/dist/cjs/utils/serialize.js +0 -77
  644. package/dist/cjs/utils/serialize.js.map +0 -1
  645. package/dist/cjs/utils/session.d.ts +0 -124
  646. package/dist/cjs/utils/session.d.ts.map +0 -1
  647. package/dist/cjs/utils/session.js +0 -396
  648. package/dist/cjs/utils/session.js.map +0 -1
  649. package/dist/constants/index.d.ts +0 -2
  650. package/dist/constants/index.d.ts.map +0 -1
  651. package/dist/constants/index.js +0 -4
  652. package/dist/constants/index.js.map +0 -1
  653. package/dist/core/AutoChainExecutor.d.ts +0 -97
  654. package/dist/core/AutoChainExecutor.d.ts.map +0 -1
  655. package/dist/core/AutoChainExecutor.js +0 -284
  656. package/dist/core/AutoChainExecutor.js.map +0 -1
  657. package/dist/core/BranchEvaluator.d.ts +0 -55
  658. package/dist/core/BranchEvaluator.d.ts.map +0 -1
  659. package/dist/core/BranchEvaluator.js +0 -121
  660. package/dist/core/BranchEvaluator.js.map +0 -1
  661. package/dist/core/DirectiveChainTracker.d.ts +0 -49
  662. package/dist/core/DirectiveChainTracker.d.ts.map +0 -1
  663. package/dist/core/DirectiveChainTracker.js +0 -117
  664. package/dist/core/DirectiveChainTracker.js.map +0 -1
  665. package/dist/core/Events.d.ts +0 -26
  666. package/dist/core/Events.d.ts.map +0 -1
  667. package/dist/core/Events.js +0 -137
  668. package/dist/core/Events.js.map +0 -1
  669. package/dist/core/Flow.d.ts +0 -183
  670. package/dist/core/Flow.d.ts.map +0 -1
  671. package/dist/core/Flow.js +0 -547
  672. package/dist/core/Flow.js.map +0 -1
  673. package/dist/core/FlowRouter.d.ts +0 -183
  674. package/dist/core/FlowRouter.d.ts.map +0 -1
  675. package/dist/core/FlowRouter.js +0 -1043
  676. package/dist/core/FlowRouter.js.map +0 -1
  677. package/dist/core/PersistenceManager.d.ts +0 -114
  678. package/dist/core/PersistenceManager.d.ts.map +0 -1
  679. package/dist/core/PersistenceManager.js +0 -332
  680. package/dist/core/PersistenceManager.js.map +0 -1
  681. package/dist/core/PromptComposer.d.ts +0 -47
  682. package/dist/core/PromptComposer.d.ts.map +0 -1
  683. package/dist/core/PromptComposer.js +0 -393
  684. package/dist/core/PromptComposer.js.map +0 -1
  685. package/dist/core/PromptSectionCache.d.ts +0 -48
  686. package/dist/core/PromptSectionCache.d.ts.map +0 -1
  687. package/dist/core/PromptSectionCache.js +0 -104
  688. package/dist/core/PromptSectionCache.js.map +0 -1
  689. package/dist/core/ResponseEngine.d.ts +0 -43
  690. package/dist/core/ResponseEngine.d.ts.map +0 -1
  691. package/dist/core/ResponseEngine.js +0 -231
  692. package/dist/core/ResponseEngine.js.map +0 -1
  693. package/dist/core/ResponseGenerationError.d.ts +0 -30
  694. package/dist/core/ResponseGenerationError.d.ts.map +0 -1
  695. package/dist/core/ResponseGenerationError.js +0 -31
  696. package/dist/core/ResponseGenerationError.js.map +0 -1
  697. package/dist/core/ResponseModal.d.ts +0 -305
  698. package/dist/core/ResponseModal.d.ts.map +0 -1
  699. package/dist/core/ResponseModal.js +0 -1410
  700. package/dist/core/ResponseModal.js.map +0 -1
  701. package/dist/core/ResponsePipeline.d.ts +0 -220
  702. package/dist/core/ResponsePipeline.d.ts.map +0 -1
  703. package/dist/core/ResponsePipeline.js +0 -1035
  704. package/dist/core/ResponsePipeline.js.map +0 -1
  705. package/dist/core/SessionFinalizer.d.ts +0 -34
  706. package/dist/core/SessionFinalizer.d.ts.map +0 -1
  707. package/dist/core/SessionFinalizer.js +0 -84
  708. package/dist/core/SessionFinalizer.js.map +0 -1
  709. package/dist/core/SessionManager.d.ts +0 -112
  710. package/dist/core/SessionManager.d.ts.map +0 -1
  711. package/dist/core/SessionManager.js +0 -301
  712. package/dist/core/SessionManager.js.map +0 -1
  713. package/dist/core/SignalCoordinator.d.ts +0 -103
  714. package/dist/core/SignalCoordinator.d.ts.map +0 -1
  715. package/dist/core/SignalCoordinator.js +0 -203
  716. package/dist/core/SignalCoordinator.js.map +0 -1
  717. package/dist/core/SignalEvaluator.d.ts +0 -86
  718. package/dist/core/SignalEvaluator.d.ts.map +0 -1
  719. package/dist/core/SignalEvaluator.js +0 -312
  720. package/dist/core/SignalEvaluator.js.map +0 -1
  721. package/dist/core/SignalProcessor.d.ts +0 -152
  722. package/dist/core/SignalProcessor.d.ts.map +0 -1
  723. package/dist/core/SignalProcessor.js +0 -498
  724. package/dist/core/SignalProcessor.js.map +0 -1
  725. package/dist/core/Step.d.ts +0 -184
  726. package/dist/core/Step.d.ts.map +0 -1
  727. package/dist/core/Step.js +0 -594
  728. package/dist/core/Step.js.map +0 -1
  729. package/dist/core/StepLifecycle.d.ts +0 -43
  730. package/dist/core/StepLifecycle.d.ts.map +0 -1
  731. package/dist/core/StepLifecycle.js +0 -176
  732. package/dist/core/StepLifecycle.js.map +0 -1
  733. package/dist/core/StreamingToolExecutor.d.ts +0 -142
  734. package/dist/core/StreamingToolExecutor.d.ts.map +0 -1
  735. package/dist/core/StreamingToolExecutor.js +0 -483
  736. package/dist/core/StreamingToolExecutor.js.map +0 -1
  737. package/dist/core/ToolLoopExecutor.d.ts +0 -133
  738. package/dist/core/ToolLoopExecutor.d.ts.map +0 -1
  739. package/dist/core/ToolLoopExecutor.js +0 -564
  740. package/dist/core/ToolLoopExecutor.js.map +0 -1
  741. package/dist/core/ToolManager.d.ts +0 -250
  742. package/dist/core/ToolManager.d.ts.map +0 -1
  743. package/dist/core/ToolManager.js +0 -1098
  744. package/dist/core/ToolManager.js.map +0 -1
  745. package/dist/core/createAgent.d.ts +0 -35
  746. package/dist/core/createAgent.d.ts.map +0 -1
  747. package/dist/core/createAgent.js +0 -36
  748. package/dist/core/createAgent.js.map +0 -1
  749. package/dist/core/flow-namespace.d.ts +0 -64
  750. package/dist/core/flow-namespace.d.ts.map +0 -1
  751. package/dist/core/flow-namespace.js +0 -179
  752. package/dist/core/flow-namespace.js.map +0 -1
  753. package/dist/core/toolGates.d.ts +0 -24
  754. package/dist/core/toolGates.d.ts.map +0 -1
  755. package/dist/core/toolGates.js +0 -49
  756. package/dist/core/toolGates.js.map +0 -1
  757. package/dist/types/persistence.d.ts +0 -254
  758. package/dist/types/persistence.d.ts.map +0 -1
  759. package/dist/types/persistence.js +0 -6
  760. package/dist/types/persistence.js.map +0 -1
  761. package/dist/types/prompt-cache.d.ts +0 -15
  762. package/dist/types/prompt-cache.d.ts.map +0 -1
  763. package/dist/types/prompt-cache.js +0 -5
  764. package/dist/types/prompt-cache.js.map +0 -1
  765. package/dist/types/signals.d.ts +0 -263
  766. package/dist/types/signals.d.ts.map +0 -1
  767. package/dist/types/signals.js +0 -10
  768. package/dist/types/signals.js.map +0 -1
  769. package/dist/types/template.d.ts +0 -84
  770. package/dist/types/template.d.ts.map +0 -1
  771. package/dist/types/template.js +0 -2
  772. package/dist/types/template.js.map +0 -1
  773. package/dist/utils/condition.d.ts +0 -63
  774. package/dist/utils/condition.d.ts.map +0 -1
  775. package/dist/utils/condition.js +0 -230
  776. package/dist/utils/condition.js.map +0 -1
  777. package/dist/utils/event.d.ts +0 -6
  778. package/dist/utils/event.d.ts.map +0 -1
  779. package/dist/utils/event.js +0 -17
  780. package/dist/utils/event.js.map +0 -1
  781. package/dist/utils/id.d.ts +0 -33
  782. package/dist/utils/id.d.ts.map +0 -1
  783. package/dist/utils/id.js +0 -77
  784. package/dist/utils/id.js.map +0 -1
  785. package/dist/utils/serialize.d.ts +0 -36
  786. package/dist/utils/serialize.d.ts.map +0 -1
  787. package/dist/utils/serialize.js +0 -72
  788. package/dist/utils/serialize.js.map +0 -1
  789. package/dist/utils/session.d.ts +0 -124
  790. package/dist/utils/session.d.ts.map +0 -1
  791. package/dist/utils/session.js +0 -379
  792. package/dist/utils/session.js.map +0 -1
  793. package/docs/concepts/directives.md +0 -369
  794. package/docs/reference/adapters.md +0 -543
  795. package/docs/reference/create-agent.md +0 -216
  796. package/docs/reference/directive.md +0 -242
  797. package/docs/reference/signals.md +0 -368
  798. package/examples/02-data-extraction.ts +0 -90
  799. package/examples/05-branching.ts +0 -140
  800. package/examples/06-flow-control.ts +0 -103
  801. package/examples/08-persistence.ts +0 -98
  802. package/examples/09-signals.ts +0 -144
  803. package/src/adapters/MemoryAdapter.ts +0 -281
  804. package/src/adapters/MongoAdapter.ts +0 -341
  805. package/src/adapters/OpenSearchAdapter.ts +0 -693
  806. package/src/adapters/PostgreSQLAdapter.ts +0 -487
  807. package/src/adapters/PrismaAdapter.ts +0 -617
  808. package/src/adapters/RedisAdapter.ts +0 -439
  809. package/src/adapters/SQLiteAdapter.ts +0 -496
  810. package/src/adapters/index.ts +0 -43
  811. package/src/adapters/sessionRow.ts +0 -57
  812. package/src/constants/index.ts +0 -2
  813. package/src/core/AutoChainExecutor.ts +0 -397
  814. package/src/core/BranchEvaluator.ts +0 -161
  815. package/src/core/DirectiveChainTracker.ts +0 -144
  816. package/src/core/Events.ts +0 -164
  817. package/src/core/Flow.ts +0 -665
  818. package/src/core/FlowRouter.ts +0 -1540
  819. package/src/core/PersistenceManager.ts +0 -446
  820. package/src/core/PromptComposer.ts +0 -448
  821. package/src/core/PromptSectionCache.ts +0 -125
  822. package/src/core/ResponseEngine.ts +0 -338
  823. package/src/core/ResponseGenerationError.ts +0 -53
  824. package/src/core/ResponseModal.ts +0 -1902
  825. package/src/core/ResponsePipeline.ts +0 -1404
  826. package/src/core/SessionFinalizer.ts +0 -108
  827. package/src/core/SessionManager.ts +0 -372
  828. package/src/core/SignalCoordinator.ts +0 -263
  829. package/src/core/SignalEvaluator.ts +0 -404
  830. package/src/core/SignalProcessor.ts +0 -663
  831. package/src/core/Step.ts +0 -782
  832. package/src/core/StepLifecycle.ts +0 -242
  833. package/src/core/StreamingToolExecutor.ts +0 -609
  834. package/src/core/ToolLoopExecutor.ts +0 -749
  835. package/src/core/ToolManager.ts +0 -1379
  836. package/src/core/createAgent.ts +0 -40
  837. package/src/core/flow-namespace.ts +0 -227
  838. package/src/core/toolGates.ts +0 -72
  839. package/src/types/persistence.ts +0 -303
  840. package/src/types/prompt-cache.ts +0 -17
  841. package/src/types/signals.ts +0 -338
  842. package/src/types/template.ts +0 -98
  843. package/src/utils/condition.ts +0 -296
  844. package/src/utils/event.ts +0 -16
  845. package/src/utils/id.ts +0 -91
  846. package/src/utils/serialize.ts +0 -86
  847. package/src/utils/session.ts +0 -501
@@ -1,1035 +0,0 @@
1
- /**
2
- * Response processing utilities shared between respond() and respondStream() methods
3
- */
4
- import { createSession, enterStep, mergeCollected, dropUndeclaredFields, logger, historyToEvents, eventsToHistory, getLastMessageFromHistory, } from "../utils/index.js";
5
- import { enterFlow } from "../utils/session.js";
6
- import { createTemplateContext } from "../utils/template.js";
7
- import { FlowConfigurationError } from "../core/Step.js";
8
- import { evaluateBranches, createAiConditionEvaluator } from "./BranchEvaluator.js";
9
- import { DirectiveChainTracker } from "./DirectiveChainTracker.js";
10
- import { ResponseGenerationError } from "./ResponseGenerationError.js";
11
- /**
12
- * Position fields on a Directive that represent a navigation decision.
13
- * When any of these is set, the directive "wins" the turn's position decision
14
- * and downstream resolution (branches, linear, AI) must not run.
15
- */
16
- const DIRECTIVE_POSITION_FIELDS = ['goTo', 'goToStep', 'complete', 'abort', 'reset'];
17
- /**
18
- * Returns `true` if the given directive has at least one position field set.
19
- * Used as the guard at the directive-bus / branch-evaluation seam:
20
- * if the bus produced a winner with a position field, `evaluateStepBranches`
21
- * (and linear/AI selection) must not run.
22
- */
23
- export function hasDirectivePositionField(directive) {
24
- if (!directive)
25
- return false;
26
- return DIRECTIVE_POSITION_FIELDS.some((field) => directive[field] !== undefined);
27
- }
28
- /**
29
- * Compute the per-key data writes the signal phase applied to a session.
30
- * The signal phase and routing start from the same input session, so any
31
- * key whose value differs between the input and the signal output was
32
- * written by the signal phase alone (handler `updateData` calls).
33
- */
34
- function diffSignalDataWrites(before, after) {
35
- const beforeData = (before ?? {});
36
- const afterData = (after ?? {});
37
- const writes = {};
38
- for (const key of Object.keys(afterData)) {
39
- if (afterData[key] !== beforeData[key]) {
40
- writes[key] = afterData[key];
41
- }
42
- }
43
- return writes;
44
- }
45
- /**
46
- * Shared response processing logic between respond() and respondStream() methods
47
- */
48
- export class ResponsePipeline {
49
- constructor(options, getFlows, flowRouter, signalCoordinator, updateCollectedData, getSchema) {
50
- this.options = options;
51
- this.getFlows = getFlows;
52
- this.flowRouter = flowRouter;
53
- this.signalCoordinator = signalCoordinator;
54
- this.updateCollectedData = updateCollectedData;
55
- this.getSchema = getSchema;
56
- }
57
- /**
58
- * Create a fresh chain tracker for the current turn.
59
- * Call at the start of each turn; the tracker is discarded at turn end.
60
- */
61
- createChainTracker() {
62
- const maxChain = this.options.maxDirectiveChain ?? 10;
63
- this._chainTracker = new DirectiveChainTracker(maxChain);
64
- return this._chainTracker;
65
- }
66
- /**
67
- * Get the current turn's chain tracker (creates one if none exists).
68
- */
69
- get chainTracker() {
70
- if (!this._chainTracker) {
71
- return this.createChainTracker();
72
- }
73
- return this._chainTracker;
74
- }
75
- /**
76
- * Prepare context and session for response generation
77
- */
78
- async prepareResponseContext(params) {
79
- const { contextOverride, session } = params;
80
- let currentContext = params.currentContext;
81
- let contextAfterHook;
82
- // Call beforeRespond hook if configured
83
- if (this.options.hooks?.beforeRespond && currentContext !== undefined) {
84
- currentContext = await this.options.hooks.beforeRespond(currentContext);
85
- // Surface the hook result so the caller can sync it back to the agent
86
- contextAfterHook = currentContext;
87
- }
88
- // Merge context with override
89
- const effectiveContext = {
90
- ...currentContext,
91
- ...contextOverride,
92
- };
93
- // Initialize or get session (use the live session if available)
94
- const targetSession = session || params.currentSession || createSession();
95
- return {
96
- effectiveContext,
97
- session: targetSession,
98
- contextAfterHook,
99
- };
100
- }
101
- /**
102
- * Handle routing and step selection logic
103
- */
104
- async handleRoutingAndStepSelection(params) {
105
- const { session, history, context, signal, allowedFlows } = params;
106
- // PHASE 2: ROUTING + STEP SELECTION - Determine which flow and step to use (combined)
107
- let selectedFlow;
108
- let responseDirectives;
109
- let selectedStep;
110
- let isFlowComplete = false;
111
- let completedFlows = [];
112
- let targetSession = session;
113
- // Flows exited this turn via pendingDirective redirect/reset
114
- const endedFlows = [];
115
- let exitPrevFlowId;
116
- let exitPrevFlowTitle;
117
- let exitReason;
118
- // Get flows early since we need them for pending directives
119
- const flows = this.getFlows();
120
- // Routing candidates may be narrowed for this turn (entry pins); the
121
- // pendingDirective applier below still resolves targets against the FULL
122
- // registry so declared redirects always resolve.
123
- const routingFlows = allowedFlows && allowedFlows.length > 0
124
- ? flows.filter((f) => allowedFlows.includes(f.id) || allowedFlows.includes(f.title))
125
- : flows;
126
- // Check for pending directive from previous flow completion or external dispatch
127
- if (targetSession.pendingDirective) {
128
- const directive = targetSession.pendingDirective;
129
- logger.debug(`[ResponsePipeline] Applying pending directive at start of turn`);
130
- // Track directive chain depth (Requirement 22.1)
131
- const tracker = this.chainTracker;
132
- tracker.record(directive, "pending");
133
- // If abort (chain breaker), the tracker stops counting; apply normally below
134
- // Clear pendingDirective before application (unless complete.next chains another)
135
- let nextDirective = undefined;
136
- if (directive.complete &&
137
- typeof directive.complete === 'object' &&
138
- directive.complete.next) {
139
- nextDirective = directive.complete.next;
140
- }
141
- targetSession = {
142
- ...targetSession,
143
- pendingDirective: nextDirective,
144
- };
145
- // Capture the flow we're leaving so directive-driven exits surface on
146
- // the response (endedFlows).
147
- exitPrevFlowId = targetSession.currentFlow?.id;
148
- exitPrevFlowTitle = exitPrevFlowId
149
- ? flows.find((f) => f.id === exitPrevFlowId)?.title
150
- : undefined;
151
- // Apply the directive: resolve position field to a flow/step
152
- if (directive.goTo) {
153
- exitReason = 'goto';
154
- const flowTarget = typeof directive.goTo === 'string'
155
- ? directive.goTo
156
- : directive.goTo.flow;
157
- if (flowTarget) {
158
- const targetFlow = flows.find((r) => r.id === flowTarget || r.title === flowTarget);
159
- if (targetFlow) {
160
- logger.debug(`[ResponsePipeline] Pending directive goTo → flow: ${targetFlow.title}`);
161
- targetSession = enterFlow(targetSession, targetFlow.id, targetFlow.title);
162
- // Merge initial data if available
163
- if (targetFlow.initialData) {
164
- targetSession = mergeCollected(targetSession, targetFlow.initialData);
165
- }
166
- // Merge directive-carried data if present
167
- if (typeof directive.goTo === 'object' && directive.goTo.data) {
168
- targetSession = mergeCollected(targetSession, directive.goTo.data);
169
- }
170
- selectedFlow = targetFlow;
171
- // If goTo specifies a step, enter it
172
- if (typeof directive.goTo === 'object' && directive.goTo.step) {
173
- const stepTarget = directive.goTo.step;
174
- const targetStep = targetFlow.getStep(stepTarget);
175
- if (targetStep) {
176
- targetSession = enterStep(targetSession, targetStep.id, targetStep.description);
177
- selectedStep = targetStep;
178
- }
179
- }
180
- }
181
- else {
182
- logger.warn(`[FlowConfigurationError] Pending directive goTo target not found: flow "${flowTarget}" does not exist. Falling back to normal routing. Fix the goTo reference or remove the pending directive.`);
183
- }
184
- }
185
- }
186
- else if (directive.goToStep) {
187
- const stepTarget = typeof directive.goToStep === 'string'
188
- ? directive.goToStep
189
- : directive.goToStep.step;
190
- const flowTarget = typeof directive.goToStep === 'object'
191
- ? directive.goToStep.flow
192
- : undefined;
193
- if (flowTarget) {
194
- const targetFlow = flows.find((r) => r.id === flowTarget || r.title === flowTarget);
195
- if (targetFlow) {
196
- targetSession = enterFlow(targetSession, targetFlow.id, targetFlow.title);
197
- selectedFlow = targetFlow;
198
- const targetStep = targetFlow.getStep(stepTarget);
199
- if (targetStep) {
200
- targetSession = enterStep(targetSession, targetStep.id, targetStep.description);
201
- selectedStep = targetStep;
202
- }
203
- }
204
- }
205
- else if (targetSession.currentFlow) {
206
- // Step within current flow
207
- const currentFlow = flows.find(r => r.id === targetSession.currentFlow?.id);
208
- if (currentFlow) {
209
- selectedFlow = currentFlow;
210
- const targetStep = currentFlow.getStep(stepTarget);
211
- if (targetStep) {
212
- targetSession = enterStep(targetSession, targetStep.id, targetStep.description);
213
- selectedStep = targetStep;
214
- }
215
- }
216
- }
217
- }
218
- else if (directive.reset) {
219
- exitReason = 'reset';
220
- // Reset current flow
221
- if (targetSession.currentFlow) {
222
- const currentFlow = flows.find(r => r.id === targetSession.currentFlow?.id);
223
- if (currentFlow) {
224
- const resetStep = typeof directive.reset === 'object' && directive.reset.step
225
- ? directive.reset.step
226
- : undefined;
227
- selectedFlow = currentFlow;
228
- if (resetStep) {
229
- const targetStep = currentFlow.getStep(resetStep);
230
- if (targetStep) {
231
- targetSession = enterStep(targetSession, targetStep.id, targetStep.description);
232
- selectedStep = targetStep;
233
- }
234
- }
235
- else {
236
- // Reset to initial step
237
- const initialStep = currentFlow.initialStep;
238
- targetSession = enterStep(targetSession, initialStep.id, initialStep.description);
239
- selectedStep = initialStep;
240
- }
241
- }
242
- }
243
- }
244
- // For complete/abort, selectedFlow stays undefined → handled downstream
245
- // Apply state writes from the directive
246
- if (directive.dataUpdate) {
247
- targetSession = mergeCollected(targetSession, directive.dataUpdate);
248
- }
249
- // Skip FlowRouter.decideFlowAndStep — the directive resolved the position
250
- }
251
- if (exitReason &&
252
- exitPrevFlowId &&
253
- (!selectedFlow || selectedFlow.id !== exitPrevFlowId)) {
254
- endedFlows.push({ flowId: exitPrevFlowId, title: exitPrevFlowTitle, reason: exitReason });
255
- }
256
- // If no pending transition or transition handled, do normal routing.
257
- // Candidates honor allowedFlows; completion scoring runs over the same set.
258
- if (routingFlows.length > 0 && !selectedFlow) {
259
- const orchestration = await this.flowRouter.decideFlowAndStep({
260
- flows: routingFlows,
261
- session: targetSession,
262
- history,
263
- agentOptions: this.options,
264
- provider: this.options.provider,
265
- context,
266
- signal,
267
- });
268
- selectedFlow = orchestration.selectedFlow;
269
- selectedStep = orchestration.selectedStep;
270
- responseDirectives = orchestration.responseDirectives;
271
- targetSession = orchestration.session;
272
- isFlowComplete = orchestration.isFlowComplete || false;
273
- completedFlows = orchestration.completedFlows || [];
274
- // Log if flow is complete
275
- if (isFlowComplete) {
276
- logger.debug(`[ResponsePipeline] Flow complete: all required data collected or last step reached`);
277
- }
278
- }
279
- return {
280
- selectedFlow,
281
- selectedStep,
282
- responseDirectives,
283
- session: targetSession,
284
- isFlowComplete,
285
- completedFlows,
286
- ...(endedFlows.length > 0 ? { endedFlows } : {}),
287
- };
288
- }
289
- /**
290
- * Combine a routing-derived session with the signal phase's non-position
291
- * mutations. The routing session is the base — it owns position state AND
292
- * data merges such as flow initialData and directive-carried writes; the
293
- * signal phase's mutations (trigger recording under `signals`, handler
294
- * data writes) are re-applied on top. Both phases start from the same
295
- * input session, so their mutations cannot silently collide.
296
- */
297
- combineRoutingAndSignalSessions(params) {
298
- const { inputSession, signalSession, routingSession } = params;
299
- let combined = routingSession;
300
- if (signalSession.signals !== inputSession.signals) {
301
- combined = { ...combined, signals: signalSession.signals };
302
- }
303
- const signalWrites = diffSignalDataWrites(inputSession.data, signalSession.data);
304
- if (Object.keys(signalWrites).length > 0) {
305
- combined = mergeCollected(combined, signalWrites);
306
- }
307
- return combined;
308
- }
309
- /**
310
- * Determine next step and update session
311
- */
312
- async determineNextStep(params) {
313
- const { selectedFlow, selectedStep, session, isFlowComplete, context, busDirective } = params;
314
- if (!selectedFlow) {
315
- return { nextStep: undefined, session, isFlowComplete };
316
- }
317
- // ─── GUARD: directive bus winner with a position field preempts branches ───
318
- // Resolution precedence (design.md): bus > branches > linear > AI.
319
- // If the bus produced a directive with a position field (goTo, goToStep,
320
- // complete, abort, reset), that decision wins the turn. Do NOT evaluate
321
- // branches or linear/AI selection — the caller applies the bus directive.
322
- if (hasDirectivePositionField(busDirective)) {
323
- logger.debug(`[ResponsePipeline] Directive bus winner has position field — skipping branch evaluation and linear/AI selection`);
324
- return { nextStep: undefined, session, isFlowComplete };
325
- }
326
- // STEP 1 (Algorithm 1): branches win over linear chain AND flow completion.
327
- // Evaluate branches before checking isFlowComplete — a branch can redirect
328
- // even from the "last" step (which getCandidateStepsWithConditions marks as complete).
329
- if (!selectedStep) {
330
- const currentStep = session.currentFlow?.id === selectedFlow.id && session.currentStep
331
- ? selectedFlow.getStep(session.currentStep.id)
332
- : undefined;
333
- if (currentStep?.branches && currentStep.branches.length > 0) {
334
- const branchResult = await this.evaluateStepBranches(currentStep, selectedFlow, session, context);
335
- if (branchResult) {
336
- // A branch that resolved a position overrides the router's completion
337
- // proposal. Without this, a branch that parks on a step of its own
338
- // flow (`then: '<stepId>'`, `then: { reset: true }`) keeps
339
- // isFlowComplete=true, the caller drops the step it just resolved,
340
- // and the turn ends as a silent completion — no LLM call, empty
341
- // reply, flow marked completed for the rest of the session.
342
- const resolvedPosition = Boolean(branchResult.nextStep || branchResult.flowChanged);
343
- return { ...branchResult, isFlowComplete: resolvedPosition ? false : isFlowComplete };
344
- }
345
- // undefined → fall through to linear/AI selection or flow completion
346
- }
347
- }
348
- if (isFlowComplete) {
349
- return { nextStep: undefined, session, isFlowComplete: true };
350
- }
351
- let nextStep;
352
- // If we have a selected step from the combined routing decision, use it
353
- if (selectedStep) {
354
- nextStep = selectedStep;
355
- }
356
- else {
357
- // Determine current step from session if we're already in this flow
358
- const currentStep = session.currentFlow?.id === selectedFlow.id && session.currentStep
359
- ? selectedFlow.getStep(session.currentStep.id)
360
- : undefined;
361
- // Get candidate steps based on current position in the flow
362
- const candidates = await this.flowRouter.getCandidateStepsWithConditions(selectedFlow, currentStep, // Pass current step instead of undefined to maintain progression
363
- createTemplateContext({ data: session.data, session, context }));
364
- if (candidates.length > 0) {
365
- nextStep = candidates[0].step;
366
- logger.debug(`[ResponsePipeline] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new flow'}`);
367
- }
368
- else {
369
- // Fallback to initial step even if it should be skipped
370
- nextStep = selectedFlow.initialStep;
371
- logger.warn(`[FlowConfigurationError] No valid steps found in flow "${selectedFlow.title}": all candidates were skipped. Falling back to initial step "${nextStep.id}". Review step skip conditions.`);
372
- }
373
- }
374
- // Before entering the step, check if requires fields are satisfied
375
- if (nextStep.requires && nextStep.requires.length > 0) {
376
- const sessionData = session.data || {};
377
- const missingRequires = nextStep.requires.filter(field => sessionData[String(field)] === undefined);
378
- if (missingRequires.length > 0) {
379
- logger.debug(`[ResponsePipeline] Cannot enter step "${nextStep.id}": missing required fields [${missingRequires.join(', ')}]. Staying at current step.`);
380
- // Stay at current step - don't enter the next one
381
- const currentStepId = session.currentStep?.id;
382
- if (currentStepId && selectedFlow) {
383
- const currentStepInstance = selectedFlow.getStep(currentStepId);
384
- if (currentStepInstance) {
385
- nextStep = currentStepInstance;
386
- }
387
- }
388
- return { nextStep, session, isFlowComplete: false };
389
- }
390
- }
391
- // Update session with next step
392
- const updatedSession = enterStep(session, nextStep.id, nextStep.description);
393
- logger.debug(`[ResponsePipeline] Entered step: ${nextStep.id}`);
394
- return { nextStep, session: updatedSession, isFlowComplete: false };
395
- }
396
- /**
397
- * Evaluate branches on a step and resolve the `then` value.
398
- *
399
- * Resolution rules (Algorithm 1, STEP 1 + then resolution):
400
- * - String `then` → look up in current flow's step registry first (local step wins).
401
- * - Not a local step → look up in agent's flow registry; if found, treat as goTo directive.
402
- * - Neither → throw FlowConfigurationError.
403
- * - Directive `then` → apply directly (bypass directive bus merge).
404
- *
405
- * Returns the resolved { nextStep, session, flowChanged? } or undefined if no branch matched.
406
- */
407
- async evaluateStepBranches(currentStep, selectedFlow, session, context) {
408
- const history = session.history ? historyToEvents(session.history) : [];
409
- // Build the BranchPredicateContext
410
- const branchCtx = {
411
- data: session.data,
412
- context,
413
- session,
414
- history,
415
- };
416
- // Create the AI condition evaluator
417
- const aiEvaluator = createAiConditionEvaluator(this.options.provider, history, context);
418
- const result = await evaluateBranches(currentStep.branches, branchCtx, aiEvaluator);
419
- if (result === undefined) {
420
- return undefined; // No branch matched → fall through to linear/AI selection
421
- }
422
- // Task 4.3: Directive `then` value — apply directly
423
- if (typeof result === 'object' && result !== null) {
424
- const directive = result;
425
- return this.applyBranchDirective(directive, selectedFlow, session);
426
- }
427
- // Task 4.2: String `then` resolution
428
- // 1. Look up in current flow's step registry first (local step wins)
429
- const localStep = selectedFlow.getStep(result);
430
- if (localStep) {
431
- const updatedSession = enterStep(session, localStep.id, localStep.description);
432
- logger.debug(`[ResponsePipeline] Branch resolved to local step: ${localStep.id}`);
433
- return { nextStep: localStep, session: updatedSession };
434
- }
435
- // 2. Look up in agent's flow registry
436
- const flows = this.getFlows();
437
- const targetFlow = flows.find(f => f.id === result || f.title === result);
438
- if (targetFlow) {
439
- // Treat as applyDirective({ goTo: result }) — enter the target flow
440
- logger.debug(`[ResponsePipeline] Branch resolved to flow: ${targetFlow.title}`);
441
- const updatedSession = enterFlow(session, targetFlow.id, targetFlow.title);
442
- return { nextStep: undefined, session: updatedSession, flowChanged: targetFlow };
443
- }
444
- // 3. Neither → throw FlowConfigurationError
445
- throw new FlowConfigurationError(`[FlowConfigurationError] Unresolved branch target: "${result}" does not match any step in flow "${selectedFlow.id}" or any flow in the agent. ` +
446
- `Source: ${selectedFlow.id}.${currentStep.id}. Fix the branch "then" value to reference a valid step id or flow id/title.`);
447
- }
448
- /**
449
- * Apply a Directive returned by a branch entry's `then` value.
450
- * Branches bypass the directive bus — the Directive is the position decision.
451
- */
452
- applyBranchDirective(directive, selectedFlow, session) {
453
- // Track directive chain depth (Requirement 22.1)
454
- const tracker = this.chainTracker;
455
- tracker.record(directive, `branch:${selectedFlow.id}`);
456
- let updatedSession = session;
457
- // Apply state writes first
458
- if (directive.dataUpdate) {
459
- updatedSession = mergeCollected(updatedSession, directive.dataUpdate);
460
- }
461
- // Handle position fields
462
- if (directive.goToStep) {
463
- const stepTarget = typeof directive.goToStep === 'string'
464
- ? directive.goToStep
465
- : directive.goToStep.step;
466
- const flowTarget = typeof directive.goToStep === 'object'
467
- ? directive.goToStep.flow
468
- : undefined;
469
- if (flowTarget) {
470
- // Cross-flow step reference — enter the target flow first
471
- const flows = this.getFlows();
472
- const targetFlow = flows.find(f => f.id === flowTarget || f.title === flowTarget);
473
- if (targetFlow) {
474
- updatedSession = enterFlow(updatedSession, targetFlow.id, targetFlow.title);
475
- updatedSession = enterStep(updatedSession, stepTarget);
476
- // Try to resolve the target step instance for the caller
477
- const targetStepInstance = targetFlow.getStep(stepTarget);
478
- logger.debug(`[ResponsePipeline] Branch directive goToStep → ${flowTarget}.${stepTarget}`);
479
- return { nextStep: targetStepInstance || undefined, session: updatedSession, flowChanged: targetFlow };
480
- }
481
- throw new FlowConfigurationError(`[FlowConfigurationError] Branch directive goToStep targets unknown flow: "${flowTarget}" does not match any flow id or title. ` +
482
- `Fix the goToStep.flow value or use goTo to target a known flow.`);
483
- }
484
- // Local step reference
485
- const targetStep = selectedFlow.getStep(stepTarget);
486
- if (targetStep) {
487
- updatedSession = enterStep(updatedSession, targetStep.id, targetStep.description);
488
- logger.debug(`[ResponsePipeline] Branch directive goToStep → ${targetStep.id}`);
489
- return { nextStep: targetStep, session: updatedSession };
490
- }
491
- throw new FlowConfigurationError(`[FlowConfigurationError] Branch directive goToStep targets unknown step: "${stepTarget}" does not exist in flow "${selectedFlow.id}". ` +
492
- `Fix the goToStep value to reference a valid step id in the current flow.`);
493
- }
494
- if (directive.goTo) {
495
- const flowTarget = typeof directive.goTo === 'string'
496
- ? directive.goTo
497
- : directive.goTo.flow ?? directive.goTo.step;
498
- if (flowTarget) {
499
- const flows = this.getFlows();
500
- const targetFlow = flows.find(f => f.id === flowTarget || f.title === flowTarget);
501
- if (targetFlow) {
502
- updatedSession = enterFlow(updatedSession, targetFlow.id, targetFlow.title);
503
- // If goTo is an object with a step field, enter that step too
504
- if (typeof directive.goTo === 'object' && directive.goTo.step) {
505
- updatedSession = enterStep(updatedSession, directive.goTo.step);
506
- }
507
- logger.debug(`[ResponsePipeline] Branch directive goTo → ${targetFlow.title}`);
508
- return { nextStep: undefined, session: updatedSession, flowChanged: targetFlow };
509
- }
510
- throw new FlowConfigurationError(`[FlowConfigurationError] Branch directive goTo targets unknown flow: "${flowTarget}" does not match any flow id or title. ` +
511
- `Fix the goTo value to reference a valid flow.`);
512
- }
513
- }
514
- if (directive.complete) {
515
- logger.debug(`[ResponsePipeline] Branch directive complete`);
516
- return { nextStep: undefined, session: updatedSession };
517
- }
518
- if (directive.abort) {
519
- logger.debug(`[ResponsePipeline] Branch directive abort`);
520
- return { nextStep: undefined, session: updatedSession };
521
- }
522
- if (directive.reset) {
523
- const resetStep = typeof directive.reset === 'object' && directive.reset.step
524
- ? directive.reset.step
525
- : undefined;
526
- if (resetStep) {
527
- const targetStep = selectedFlow.getStep(resetStep);
528
- if (targetStep) {
529
- updatedSession = enterStep(updatedSession, targetStep.id, targetStep.description);
530
- return { nextStep: targetStep, session: updatedSession };
531
- }
532
- }
533
- // Reset to initial step
534
- const initialStep = selectedFlow.initialStep;
535
- updatedSession = enterStep(updatedSession, initialStep.id, initialStep.description);
536
- logger.debug(`[ResponsePipeline] Branch directive reset → ${initialStep.id}`);
537
- return { nextStep: initialStep, session: updatedSession };
538
- }
539
- // Directive with only non-position fields (e.g., just dataUpdate/contextUpdate/reply)
540
- // No position change — fall through to linear selection
541
- return { nextStep: undefined, session: updatedSession };
542
- }
543
- /**
544
- * TURN ROUTING + STEP SELECTION — the single entry point for deciding which
545
- * flow and step a turn renders. Runs the routing-skip optimization, the
546
- * pre-signal phase (parallel with routing when a processor is configured),
547
- * pre-extraction, and next-step determination.
548
- */
549
- async routeAndSelectStep(params) {
550
- try {
551
- // Create a fresh chain tracker for this turn (Requirement 22.1)
552
- this.createChainTracker();
553
- // ROUTING SKIP OPTIMIZATION (Requirements 20.1, 20.2, 20.3):
554
- // When the current step has collect fields AND step-scoped pre-extraction
555
- // populates at least one of those fields, skip FlowRouter.decideFlowAndStep
556
- // for this turn. The check's extraction result is reused by the fallthrough
557
- // paths below so a turn costs at most ONE extraction LLM call.
558
- const routingSkipCheck = await this.attemptRoutingSkipForCollect(params);
559
- if (routingSkipCheck.skipResult) {
560
- const skipResult = routingSkipCheck.skipResult;
561
- // Even when routing is skipped, run pre-signal phase if processor is present
562
- if (this.signalCoordinator.enabled) {
563
- const signalResult = await this.signalCoordinator.runPrePhase(params.session, params.context, params.history);
564
- // If signal halts, override the routing skip result
565
- if (signalResult.mergedDirective?.halt) {
566
- return {
567
- ...skipResult,
568
- session: signalResult.updatedSession,
569
- signalFirings: signalResult.firings,
570
- signalHalted: true,
571
- signalHaltReply: signalResult.mergedDirective.reply,
572
- };
573
- }
574
- // If signal has position fields, override routing skip result
575
- if (hasDirectivePositionField(signalResult.mergedDirective)) {
576
- return this.signalCoordinator.applyPositionDirective(signalResult);
577
- }
578
- // Non-position directive: keep the skip result (extraction merges,
579
- // step entry) and re-apply the signal phase's non-position mutations
580
- return {
581
- ...skipResult,
582
- session: this.combineRoutingAndSignalSessions({
583
- inputSession: params.session,
584
- signalSession: signalResult.updatedSession,
585
- routingSession: skipResult.session,
586
- }),
587
- signalFirings: signalResult.firings,
588
- signalPreDirective: signalResult.mergedDirective || undefined,
589
- };
590
- }
591
- return skipResult;
592
- }
593
- // ── PARALLEL PRE-SIGNAL PHASE + ROUTING (Algorithm 5) ────────────────
594
- // When signalProcessor is present, run pre-signals in parallel with routing.
595
- // When absent, call the router directly (zero overhead, preserve current behavior).
596
- if (this.signalCoordinator.enabled) {
597
- // Run pre-signal phase in parallel with routing (Requirement 8.1)
598
- const [signalResult, routingResult] = await Promise.all([
599
- this.signalCoordinator.runPrePhase(params.session, params.context, params.history),
600
- this.handleRoutingAndStepSelection({
601
- session: params.session,
602
- history: params.history,
603
- context: params.context,
604
- signal: params.signal,
605
- allowedFlows: params.allowedFlows,
606
- }),
607
- ]);
608
- // ── Requirement 8.2: halt → discard routing, skip LLM ────────────
609
- if (signalResult.mergedDirective?.halt) {
610
- return {
611
- selectedFlow: undefined,
612
- selectedStep: undefined,
613
- session: signalResult.updatedSession,
614
- isFlowComplete: false,
615
- signalFirings: signalResult.firings,
616
- signalHalted: true,
617
- signalHaltReply: signalResult.mergedDirective.reply,
618
- };
619
- }
620
- // ── Requirement 8.3: position directive → discard routing, apply signal position ──
621
- if (hasDirectivePositionField(signalResult.mergedDirective)) {
622
- return this.signalCoordinator.applyPositionDirective(signalResult);
623
- }
624
- // ── Requirement 8.4: non-position directive → use routing, propagate augmentation ──
625
- // ── Requirement 8.5: no directive → use routing as-is ─────────────
626
- // Base = routed session (position state AND router data merges such as
627
- // flow initialData survive); the signal phase's non-position mutations
628
- // (trigger state, handler data writes) are re-applied on top.
629
- let updatedSession = this.combineRoutingAndSignalSessions({
630
- inputSession: params.session,
631
- signalSession: signalResult.updatedSession,
632
- routingSession: routingResult.session,
633
- });
634
- // Explicit dataUpdate from the signal's merged directive lands last
635
- if (signalResult.mergedDirective?.dataUpdate) {
636
- updatedSession = mergeCollected(updatedSession, signalResult.mergedDirective.dataUpdate);
637
- }
638
- const isFlowComplete = routingResult.isFlowComplete;
639
- // PRE-EXTRACTION: same logic as below — extract data from user message.
640
- // Reuses the routing-skip check's step-scoped extraction when it already
641
- // ran this turn (at most ONE extraction LLM call per turn).
642
- if (routingResult.selectedFlow && !isFlowComplete) {
643
- let extractedData;
644
- if (routingSkipCheck.extractionRan) {
645
- extractedData = routingSkipCheck.extractedData;
646
- }
647
- else if (this.shouldPreExtractData(routingResult.selectedFlow)) {
648
- logger.debug(`[ResponsePipeline] Pre-extracting data for flow: ${routingResult.selectedFlow.title}`);
649
- extractedData = await this.preExtractFlowData({
650
- route: routingResult.selectedFlow,
651
- history: params.history,
652
- context: params.context,
653
- session: updatedSession,
654
- signal: params.signal,
655
- });
656
- }
657
- if (extractedData && Object.keys(extractedData).length > 0) {
658
- logger.debug(`[ResponsePipeline] Pre-extracted data:`, extractedData);
659
- updatedSession = mergeCollected(updatedSession, extractedData);
660
- await this.updateCollectedData(extractedData);
661
- }
662
- }
663
- // Determine next step
664
- const stepResult = await this.determineNextStep({
665
- selectedFlow: routingResult.selectedFlow,
666
- selectedStep: routingResult.selectedStep,
667
- session: updatedSession,
668
- isFlowComplete,
669
- context: params.context,
670
- });
671
- return {
672
- selectedFlow: stepResult.flowChanged || routingResult.selectedFlow,
673
- selectedStep: stepResult.nextStep,
674
- responseDirectives: routingResult.responseDirectives,
675
- session: stepResult.session,
676
- isFlowComplete: stepResult.isFlowComplete,
677
- signalFirings: signalResult.firings,
678
- signalPreDirective: signalResult.mergedDirective || undefined,
679
- endedFlows: routingResult.endedFlows,
680
- };
681
- }
682
- // ── No signal processor: existing behavior (zero overhead) ────────────
683
- const routingResult = await this.handleRoutingAndStepSelection({
684
- session: params.session,
685
- history: params.history,
686
- context: params.context,
687
- signal: params.signal,
688
- allowedFlows: params.allowedFlows,
689
- });
690
- let updatedSession = routingResult.session;
691
- const isFlowComplete = routingResult.isFlowComplete;
692
- // PRE-EXTRACTION: If entering a flow that collects data, extract data from user message first
693
- // This allows us to skip steps whose data is already provided.
694
- // Reuses the routing-skip check's step-scoped extraction when it already
695
- // ran this turn — at most ONE extraction LLM call per turn.
696
- if (routingResult.selectedFlow && !isFlowComplete) {
697
- // Always pre-extract when flow collects data (not just on new flow entry)
698
- // This ensures step selection has the most up-to-date data
699
- let extractedData;
700
- if (routingSkipCheck.extractionRan) {
701
- extractedData = routingSkipCheck.extractedData;
702
- }
703
- else if (this.shouldPreExtractData(routingResult.selectedFlow)) {
704
- logger.debug(`[ResponsePipeline] Pre-extracting data for flow: ${routingResult.selectedFlow.title}`);
705
- extractedData = await this.preExtractFlowData({
706
- route: routingResult.selectedFlow,
707
- history: params.history,
708
- context: params.context,
709
- session: updatedSession,
710
- signal: params.signal,
711
- });
712
- }
713
- if (extractedData && Object.keys(extractedData).length > 0) {
714
- logger.debug(`[ResponsePipeline] Pre-extracted data:`, extractedData);
715
- // Merge pre-extracted data into session before step selection
716
- updatedSession = mergeCollected(updatedSession, extractedData);
717
- // Also update agent's collected data
718
- await this.updateCollectedData(extractedData);
719
- }
720
- }
721
- // Determine next step using pipeline method for consistency
722
- const stepResult = await this.determineNextStep({
723
- selectedFlow: routingResult.selectedFlow,
724
- selectedStep: routingResult.selectedStep,
725
- session: updatedSession, // Use updated session with pre-extracted data
726
- isFlowComplete, // Use updated completion status
727
- context: params.context,
728
- });
729
- return {
730
- selectedFlow: stepResult.flowChanged || routingResult.selectedFlow,
731
- selectedStep: stepResult.nextStep, // Use the determined next step
732
- responseDirectives: routingResult.responseDirectives,
733
- session: stepResult.session,
734
- // determineNextStep owns the verdict: a branch that resolved a position
735
- // (new flow, or a step of this one) overrides the router's proposal.
736
- isFlowComplete: stepResult.isFlowComplete,
737
- endedFlows: routingResult.endedFlows,
738
- };
739
- }
740
- catch (error) {
741
- throw ResponseGenerationError.fromError(error, 'routing_optimization', params);
742
- }
743
- }
744
- /**
745
- * RENDER-STEP RESOLUTION — resolve the step a flow response will render,
746
- * shared by the streaming and non-streaming paths. When no step was
747
- * pre-selected: branches win over the linear chain, then candidate steps,
748
- * then the initial-step fallback. Enforces `requires` (stays at the current
749
- * step when required fields are missing) and enters the resolved step.
750
- *
751
- * Returns `flowTransition: true` when a branch resolved to a flow
752
- * transition or completion — there is no local step to render and the
753
- * caller handles the transition.
754
- */
755
- async resolveRenderStep(params) {
756
- const { selectedFlow, selectedStep, context } = params;
757
- let session = params.session;
758
- // Determine next step
759
- let nextStep;
760
- if (selectedStep) {
761
- nextStep = selectedStep;
762
- }
763
- else {
764
- // Determine current step from session if we're already in this flow
765
- const isInSameFlow = session.currentFlow?.id === selectedFlow.id;
766
- const currentStep = isInSameFlow && session.currentStep
767
- ? selectedFlow.getStep(session.currentStep.id)
768
- : undefined;
769
- logger.debug(`[ResponsePipeline] Step determination: flow match=${isInSameFlow}, currentFlow=${session.currentFlow?.id}, selectedFlow=${selectedFlow.id}, currentStep=${currentStep?.id || 'none'}`);
770
- // STEP 1 (Algorithm 1): branches win over linear chain
771
- if (currentStep?.branches && currentStep.branches.length > 0) {
772
- const branchResult = await this.evaluateStepBranches(currentStep, selectedFlow, session, context);
773
- if (branchResult) {
774
- if (branchResult.nextStep) {
775
- nextStep = branchResult.nextStep;
776
- session = branchResult.session;
777
- }
778
- else {
779
- // Flow transition or completion — no local step to render
780
- return { nextStep: undefined, session: branchResult.session, flowTransition: true };
781
- }
782
- }
783
- }
784
- if (!nextStep) {
785
- // Get candidate steps based on current position in the flow
786
- const candidates = await this.flowRouter.getCandidateStepsWithConditions(selectedFlow, currentStep, // Pass current step instead of undefined to maintain progression
787
- createTemplateContext({ data: session.data, session, context }));
788
- logger.debug(`[ResponsePipeline] Found ${candidates.length} candidate steps${currentStep ? ' from current step ' + currentStep.id : ' (new flow entry)'}`);
789
- if (candidates.length > 0) {
790
- nextStep = candidates[0].step;
791
- logger.debug(`[ResponsePipeline] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new flow'}`);
792
- }
793
- else {
794
- // Fallback to initial step even if it should be skipped
795
- nextStep = selectedFlow.initialStep;
796
- logger.warn(`[FlowConfigurationError] No valid steps found: all candidates were skipped in flow. Falling back to initial step "${nextStep.id}". Review step skip conditions.`);
797
- }
798
- }
799
- }
800
- // Update session with next step
801
- // If the next step has requires fields that are missing, stay at the previous step
802
- if (nextStep.requires && nextStep.requires.length > 0) {
803
- const sessionData = session.data || {};
804
- const missingRequires = nextStep.requires.filter(field => sessionData[String(field)] === undefined);
805
- if (missingRequires.length > 0) {
806
- const warning = `[FlowConfigurationError] Cannot advance to step "${nextStep.description || nextStep.id}": ` +
807
- `missing required fields [${missingRequires.join(', ')}]. Staying at current step. Ensure preceding steps collect these fields.`;
808
- logger.warn(warning);
809
- console.warn(warning);
810
- // Stay at the current step - don't enter the next one
811
- const currentStepId = session.currentStep?.id;
812
- if (currentStepId) {
813
- const currentStepInstance = selectedFlow.getStep(currentStepId);
814
- if (currentStepInstance) {
815
- nextStep = currentStepInstance;
816
- logger.debug(`[ResponsePipeline] Staying at current step: ${nextStep.id} due to missing requires`);
817
- }
818
- }
819
- }
820
- else {
821
- session = enterStep(session, nextStep.id, nextStep.description);
822
- logger.debug(`[ResponsePipeline] Entered step: ${nextStep.id}`);
823
- }
824
- }
825
- else {
826
- session = enterStep(session, nextStep.id, nextStep.description);
827
- logger.debug(`[ResponsePipeline] Entered step: ${nextStep.id}`);
828
- }
829
- return { nextStep, session, flowTransition: false };
830
- }
831
- /**
832
- * Routing skip check (Requirements 20.1, 20.2, 20.3):
833
- * When the current step declares `collect` fields AND step-scoped extraction
834
- * populates at least one of those fields from the user's message, the caller
835
- * skips routing for this turn (`skipResult`).
836
- *
837
- * The extraction is scoped to EXACTLY this step's collect fields — incidental
838
- * mentions of other (e.g. other-flow) fields cannot pin the routing decision.
839
- * It is skipped entirely when every collect field is already populated.
840
- *
841
- * Always returns what the check did so the caller can reuse the single
842
- * extraction result in its normal path instead of extracting twice:
843
- * - `extractionRan` — whether an extraction LLM call was made this turn.
844
- * - `extractedData` — that call's result (empty when nothing found / not run).
845
- */
846
- async attemptRoutingSkipForCollect(params) {
847
- const { session } = params;
848
- const notApplicable = { extractionRan: false, extractedData: {} };
849
- // Only applies when we already have a current flow and step
850
- if (!session.currentFlow || !session.currentStep) {
851
- return notApplicable;
852
- }
853
- // Also skip this optimization if there's a pending directive (it takes priority)
854
- if (session.pendingDirective) {
855
- return notApplicable;
856
- }
857
- // Look up the actual Flow and Step objects to access `collect`
858
- const currentFlow = this.getFlows().find((f) => f.id === session.currentFlow?.id);
859
- if (!currentFlow) {
860
- return notApplicable;
861
- }
862
- const currentStep = currentFlow.getStep(session.currentStep.id);
863
- if (!currentStep || !currentStep.collect || currentStep.collect.length === 0) {
864
- return notApplicable;
865
- }
866
- const collectFields = currentStep.collect;
867
- // Every relevant field already set — the skip cannot fire; don't spend
868
- // an extraction LLM call probing for it.
869
- const sessionRecord = (session.data ?? {});
870
- const allPopulated = collectFields.every((field) => {
871
- const value = sessionRecord[String(field)];
872
- return value !== undefined && value !== null;
873
- });
874
- if (allPopulated) {
875
- return notApplicable;
876
- }
877
- // Snapshot current data for comparison
878
- const dataBefore = { ...sessionRecord };
879
- // Step-scoped pre-extraction: see if the user's message populates any of
880
- // THIS step's collect fields.
881
- const extractedData = await this.preExtractFlowData({
882
- route: currentFlow,
883
- history: params.history,
884
- context: params.context,
885
- session,
886
- signal: params.signal,
887
- restrictToFields: collectFields.map(String),
888
- });
889
- if (!extractedData || Object.keys(extractedData).length === 0) {
890
- return { extractionRan: true, extractedData: {} };
891
- }
892
- // Determine which collect fields were newly populated by pre-extraction
893
- const extractedRecord = extractedData;
894
- const populatedCollectFields = [];
895
- for (const field of collectFields) {
896
- const key = String(field);
897
- const hadValue = dataBefore[key] !== undefined && dataBefore[key] !== null;
898
- const hasNewValue = extractedRecord[key] !== undefined && extractedRecord[key] !== null;
899
- if (hasNewValue && !hadValue) {
900
- populatedCollectFields.push(key);
901
- }
902
- }
903
- if (populatedCollectFields.length === 0) {
904
- // Pre-extraction didn't populate any declared collect field — no skip
905
- return { extractionRan: true, extractedData };
906
- }
907
- // ROUTING SKIP: pre-extraction populated collect fields → retain current flow/step
908
- logger.debug(`[ResponsePipeline] Routing skip: pre-extraction populated collect fields [${populatedCollectFields.join(', ')}] for step "${currentStep.id}" — skipping FlowRouter`);
909
- // Merge extracted data into session
910
- const updatedSession = mergeCollected(session, extractedData);
911
- await this.updateCollectedData(extractedData);
912
- // Determine next step using pipeline method for consistency
913
- // Pass the current flow/step as the routing result (retained)
914
- const stepResult = await this.determineNextStep({
915
- selectedFlow: currentFlow,
916
- selectedStep: currentStep,
917
- session: updatedSession,
918
- isFlowComplete: false,
919
- context: params.context,
920
- });
921
- return {
922
- extractionRan: true,
923
- extractedData,
924
- skipResult: {
925
- selectedFlow: stepResult.flowChanged || currentFlow,
926
- selectedStep: stepResult.nextStep,
927
- responseDirectives: undefined,
928
- session: stepResult.session,
929
- isFlowComplete: stepResult.isFlowComplete,
930
- },
931
- };
932
- }
933
- /**
934
- * Check if a flow should pre-extract data before determining the initial step
935
- */
936
- shouldPreExtractData(flow) {
937
- // Pre-extract if flow has declared required or optional fields
938
- if (flow.requiredFields && flow.requiredFields.length > 0) {
939
- return true;
940
- }
941
- if (flow.optionalFields && flow.optionalFields.length > 0) {
942
- return true;
943
- }
944
- // Pre-extract if any step in the flow collects data
945
- const steps = flow.getAllSteps();
946
- const hasDataCollectionSteps = steps.some(step => step.collect && step.collect.length > 0);
947
- return hasDataCollectionSteps;
948
- }
949
- /**
950
- * Build an extraction schema limited to the given subset of agent schema
951
- * fields. Used by the routing-skip probe so only the current step's collect
952
- * fields are visible to the extractor.
953
- */
954
- buildFieldRestrictedSchema(agentSchema, fields) {
955
- const properties = {};
956
- for (const field of fields) {
957
- const prop = agentSchema.properties?.[field];
958
- if (prop) {
959
- properties[field] = prop;
960
- }
961
- }
962
- return {
963
- type: "object",
964
- description: `Extraction restricted to these fields: ${fields.join(', ')}`,
965
- properties,
966
- additionalProperties: false,
967
- };
968
- }
969
- /**
970
- * Pre-extract data from user message when entering a flow
971
- * This allows skipping steps whose data is already provided
972
- */
973
- async preExtractFlowData(params) {
974
- const { route: flow, history, signal, restrictToFields } = params;
975
- // Build a schema for data extraction based on flow's fields
976
- const agentSchema = this.getSchema();
977
- if (!agentSchema) {
978
- logger.warn(`[ResponsePipeline] No schema available for pre-extraction`);
979
- return {};
980
- }
981
- const extractionSchema = restrictToFields
982
- ? this.buildFieldRestrictedSchema(agentSchema, restrictToFields)
983
- : agentSchema;
984
- // Get last user message
985
- const lastMessage = getLastMessageFromHistory(history);
986
- // Build extraction prompt
987
- const extractionPrompt = [
988
- `Extract any relevant information from the user's message that matches the following data fields.`,
989
- `Only extract information that is explicitly stated or clearly implied.`,
990
- ``,
991
- `User's message: "${lastMessage}"`,
992
- ``,
993
- `Extract data for these fields if present:`,
994
- ];
995
- // Add field descriptions
996
- if (restrictToFields) {
997
- extractionPrompt.push(`Only these fields: ${restrictToFields.join(', ')}`);
998
- }
999
- else {
1000
- if (flow.requiredFields) {
1001
- extractionPrompt.push(`Required fields: ${flow.requiredFields.join(', ')}`);
1002
- }
1003
- if (flow.optionalFields) {
1004
- extractionPrompt.push(`Optional fields: ${flow.optionalFields.join(', ')}`);
1005
- }
1006
- }
1007
- extractionPrompt.push(``, `Return ONLY the extracted data as JSON. If no data can be extracted, return an empty object {}.`);
1008
- // Convert Event[] to HistoryItem[] for provider call
1009
- const historyItems = eventsToHistory(history);
1010
- // Call AI to extract data
1011
- try {
1012
- const result = await this.options.provider.generateMessage({
1013
- prompt: extractionPrompt.join('\n'),
1014
- history: historyItems,
1015
- context: {}, // Passed as empty object so AI doesn't "extract" from context
1016
- // NOTE: context is intentionally NOT passed here.
1017
- // Passing context caused the AI to "extract" data from the lead's context
1018
- // (e.g., name, sector, city) instead of from what the user actually said.
1019
- signal,
1020
- parameters: {
1021
- jsonSchema: extractionSchema,
1022
- schemaName: 'data_extraction',
1023
- },
1024
- });
1025
- // Every caller merges this into the turn session BEFORE updateCollectedData
1026
- // runs, so an undeclared key is dropped here, at the source
1027
- return dropUndeclaredFields(result.structured || {}, agentSchema);
1028
- }
1029
- catch (error) {
1030
- logger.error(`[ResponsePipeline] Pre-extraction failed:`, error);
1031
- return {};
1032
- }
1033
- }
1034
- }
1035
- //# sourceMappingURL=ResponsePipeline.js.map