@falai/agent 0.6.9 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/README.md +62 -59
  2. package/dist/adapters/MemoryAdapter.js +2 -2
  3. package/dist/adapters/MemoryAdapter.js.map +1 -1
  4. package/dist/adapters/MongoAdapter.js +2 -2
  5. package/dist/adapters/MongoAdapter.js.map +1 -1
  6. package/dist/adapters/OpenSearchAdapter.js +7 -7
  7. package/dist/adapters/OpenSearchAdapter.js.map +1 -1
  8. package/dist/adapters/PostgreSQLAdapter.js +9 -9
  9. package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
  10. package/dist/adapters/PrismaAdapter.js +3 -3
  11. package/dist/adapters/PrismaAdapter.js.map +1 -1
  12. package/dist/adapters/RedisAdapter.js +2 -2
  13. package/dist/adapters/RedisAdapter.js.map +1 -1
  14. package/dist/adapters/SQLiteAdapter.d.ts +3 -3
  15. package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
  16. package/dist/adapters/SQLiteAdapter.js +11 -11
  17. package/dist/adapters/SQLiteAdapter.js.map +1 -1
  18. package/dist/adapters/index.d.ts +1 -1
  19. package/dist/adapters/index.d.ts.map +1 -1
  20. package/dist/cjs/adapters/MemoryAdapter.js +2 -2
  21. package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
  22. package/dist/cjs/adapters/MongoAdapter.js +2 -2
  23. package/dist/cjs/adapters/MongoAdapter.js.map +1 -1
  24. package/dist/cjs/adapters/OpenSearchAdapter.js +7 -7
  25. package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -1
  26. package/dist/cjs/adapters/PostgreSQLAdapter.js +9 -9
  27. package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
  28. package/dist/cjs/adapters/PrismaAdapter.js +3 -3
  29. package/dist/cjs/adapters/PrismaAdapter.js.map +1 -1
  30. package/dist/cjs/adapters/RedisAdapter.js +2 -2
  31. package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
  32. package/dist/cjs/adapters/SQLiteAdapter.d.ts +3 -3
  33. package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
  34. package/dist/cjs/adapters/SQLiteAdapter.js +11 -11
  35. package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -1
  36. package/dist/cjs/adapters/index.d.ts +1 -1
  37. package/dist/cjs/adapters/index.d.ts.map +1 -1
  38. package/dist/cjs/constants/index.d.ts +4 -4
  39. package/dist/cjs/constants/index.js +5 -5
  40. package/dist/cjs/core/Agent.d.ts +22 -22
  41. package/dist/cjs/core/Agent.d.ts.map +1 -1
  42. package/dist/cjs/core/Agent.js +160 -152
  43. package/dist/cjs/core/Agent.js.map +1 -1
  44. package/dist/cjs/core/Events.d.ts +6 -6
  45. package/dist/cjs/core/Events.d.ts.map +1 -1
  46. package/dist/cjs/core/PersistenceManager.d.ts +13 -13
  47. package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
  48. package/dist/cjs/core/PersistenceManager.js +24 -24
  49. package/dist/cjs/core/PersistenceManager.js.map +1 -1
  50. package/dist/cjs/core/ResponseEngine.d.ts +3 -8
  51. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
  52. package/dist/cjs/core/ResponseEngine.js +8 -8
  53. package/dist/cjs/core/ResponseEngine.js.map +1 -1
  54. package/dist/cjs/core/Route.d.ts +17 -17
  55. package/dist/cjs/core/Route.d.ts.map +1 -1
  56. package/dist/cjs/core/Route.js +33 -33
  57. package/dist/cjs/core/Route.js.map +1 -1
  58. package/dist/cjs/core/RoutingEngine.d.ts +30 -30
  59. package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
  60. package/dist/cjs/core/RoutingEngine.js +192 -192
  61. package/dist/cjs/core/RoutingEngine.js.map +1 -1
  62. package/dist/cjs/core/Step.d.ts +72 -0
  63. package/dist/cjs/core/Step.d.ts.map +1 -0
  64. package/dist/cjs/core/Step.js +150 -0
  65. package/dist/cjs/core/Step.js.map +1 -0
  66. package/dist/cjs/core/ToolExecutor.d.ts +5 -5
  67. package/dist/cjs/core/ToolExecutor.d.ts.map +1 -1
  68. package/dist/cjs/core/ToolExecutor.js +8 -8
  69. package/dist/cjs/core/ToolExecutor.js.map +1 -1
  70. package/dist/cjs/core/Transition.d.ts +14 -14
  71. package/dist/cjs/core/Transition.d.ts.map +1 -1
  72. package/dist/cjs/core/Transition.js +48 -19
  73. package/dist/cjs/core/Transition.js.map +1 -1
  74. package/dist/cjs/index.d.ts +7 -7
  75. package/dist/cjs/index.d.ts.map +1 -1
  76. package/dist/cjs/index.js +8 -8
  77. package/dist/cjs/index.js.map +1 -1
  78. package/dist/cjs/types/agent.d.ts +8 -8
  79. package/dist/cjs/types/agent.d.ts.map +1 -1
  80. package/dist/cjs/types/ai.d.ts +2 -2
  81. package/dist/cjs/types/ai.d.ts.map +1 -1
  82. package/dist/cjs/types/history.d.ts +3 -3
  83. package/dist/cjs/types/history.d.ts.map +1 -1
  84. package/dist/cjs/types/index.d.ts +1 -1
  85. package/dist/cjs/types/index.d.ts.map +1 -1
  86. package/dist/cjs/types/persistence.d.ts +5 -5
  87. package/dist/cjs/types/persistence.d.ts.map +1 -1
  88. package/dist/cjs/types/route.d.ts +57 -52
  89. package/dist/cjs/types/route.d.ts.map +1 -1
  90. package/dist/cjs/types/session.d.ts +27 -27
  91. package/dist/cjs/types/session.d.ts.map +1 -1
  92. package/dist/cjs/types/session.js +48 -50
  93. package/dist/cjs/types/session.js.map +1 -1
  94. package/dist/cjs/types/tool.d.ts +13 -13
  95. package/dist/cjs/types/tool.d.ts.map +1 -1
  96. package/dist/cjs/utils/id.d.ts +8 -3
  97. package/dist/cjs/utils/id.d.ts.map +1 -1
  98. package/dist/cjs/utils/id.js +16 -7
  99. package/dist/cjs/utils/id.js.map +1 -1
  100. package/dist/constants/index.d.ts +4 -4
  101. package/dist/constants/index.js +4 -4
  102. package/dist/core/Agent.d.ts +22 -22
  103. package/dist/core/Agent.d.ts.map +1 -1
  104. package/dist/core/Agent.js +162 -154
  105. package/dist/core/Agent.js.map +1 -1
  106. package/dist/core/Events.d.ts +6 -6
  107. package/dist/core/Events.d.ts.map +1 -1
  108. package/dist/core/PersistenceManager.d.ts +13 -13
  109. package/dist/core/PersistenceManager.d.ts.map +1 -1
  110. package/dist/core/PersistenceManager.js +25 -25
  111. package/dist/core/PersistenceManager.js.map +1 -1
  112. package/dist/core/ResponseEngine.d.ts +3 -8
  113. package/dist/core/ResponseEngine.d.ts.map +1 -1
  114. package/dist/core/ResponseEngine.js +8 -8
  115. package/dist/core/ResponseEngine.js.map +1 -1
  116. package/dist/core/Route.d.ts +17 -17
  117. package/dist/core/Route.d.ts.map +1 -1
  118. package/dist/core/Route.js +33 -33
  119. package/dist/core/Route.js.map +1 -1
  120. package/dist/core/RoutingEngine.d.ts +30 -30
  121. package/dist/core/RoutingEngine.d.ts.map +1 -1
  122. package/dist/core/RoutingEngine.js +193 -193
  123. package/dist/core/RoutingEngine.js.map +1 -1
  124. package/dist/core/Step.d.ts +72 -0
  125. package/dist/core/Step.d.ts.map +1 -0
  126. package/dist/core/Step.js +146 -0
  127. package/dist/core/Step.js.map +1 -0
  128. package/dist/core/ToolExecutor.d.ts +5 -5
  129. package/dist/core/ToolExecutor.d.ts.map +1 -1
  130. package/dist/core/ToolExecutor.js +8 -8
  131. package/dist/core/ToolExecutor.js.map +1 -1
  132. package/dist/core/Transition.d.ts +14 -14
  133. package/dist/core/Transition.d.ts.map +1 -1
  134. package/dist/core/Transition.js +48 -19
  135. package/dist/core/Transition.js.map +1 -1
  136. package/dist/index.d.ts +7 -7
  137. package/dist/index.d.ts.map +1 -1
  138. package/dist/index.js +4 -4
  139. package/dist/index.js.map +1 -1
  140. package/dist/types/agent.d.ts +8 -8
  141. package/dist/types/agent.d.ts.map +1 -1
  142. package/dist/types/ai.d.ts +2 -2
  143. package/dist/types/ai.d.ts.map +1 -1
  144. package/dist/types/history.d.ts +3 -3
  145. package/dist/types/history.d.ts.map +1 -1
  146. package/dist/types/index.d.ts +1 -1
  147. package/dist/types/index.d.ts.map +1 -1
  148. package/dist/types/persistence.d.ts +5 -5
  149. package/dist/types/persistence.d.ts.map +1 -1
  150. package/dist/types/route.d.ts +57 -52
  151. package/dist/types/route.d.ts.map +1 -1
  152. package/dist/types/session.d.ts +27 -27
  153. package/dist/types/session.d.ts.map +1 -1
  154. package/dist/types/session.js +44 -46
  155. package/dist/types/session.js.map +1 -1
  156. package/dist/types/tool.d.ts +13 -13
  157. package/dist/types/tool.d.ts.map +1 -1
  158. package/dist/utils/id.d.ts +8 -3
  159. package/dist/utils/id.d.ts.map +1 -1
  160. package/dist/utils/id.js +14 -6
  161. package/dist/utils/id.js.map +1 -1
  162. package/docs/ADAPTERS.md +21 -21
  163. package/docs/AGENT.md +57 -55
  164. package/docs/API_REFERENCE.md +218 -220
  165. package/docs/ARCHITECTURE.md +99 -104
  166. package/docs/CONTEXT_MANAGEMENT.md +81 -88
  167. package/docs/DOCS.md +18 -18
  168. package/docs/DOMAINS.md +16 -16
  169. package/docs/EXAMPLES.md +43 -43
  170. package/docs/GETTING_STARTED.md +60 -63
  171. package/docs/PERSISTENCE.md +66 -70
  172. package/docs/PROVIDERS.md +2 -2
  173. package/docs/README.md +6 -6
  174. package/docs/ROUTES.md +218 -220
  175. package/docs/STEPS.md +883 -0
  176. package/examples/business-onboarding.ts +84 -81
  177. package/examples/company-qna-agent.ts +68 -67
  178. package/examples/custom-database-persistence.ts +87 -89
  179. package/examples/declarative-agent.ts +32 -32
  180. package/examples/domain-scoping.ts +18 -18
  181. package/examples/extracted-data-modification.ts +92 -97
  182. package/examples/healthcare-agent.ts +89 -91
  183. package/examples/openai-agent.ts +29 -32
  184. package/examples/opensearch-persistence.ts +43 -45
  185. package/examples/persistent-onboarding.ts +65 -66
  186. package/examples/prisma-persistence.ts +108 -112
  187. package/examples/prisma-schema.example.prisma +3 -3
  188. package/examples/redis-persistence.ts +67 -73
  189. package/examples/route-transitions.ts +71 -47
  190. package/examples/rules-prohibitions.ts +28 -28
  191. package/examples/streaming-agent.ts +24 -24
  192. package/examples/travel-agent.ts +94 -109
  193. package/package.json +1 -1
  194. package/src/adapters/MemoryAdapter.ts +3 -3
  195. package/src/adapters/MongoAdapter.ts +3 -3
  196. package/src/adapters/OpenSearchAdapter.ts +8 -8
  197. package/src/adapters/PostgreSQLAdapter.ts +10 -10
  198. package/src/adapters/PrismaAdapter.ts +4 -4
  199. package/src/adapters/RedisAdapter.ts +3 -3
  200. package/src/adapters/SQLiteAdapter.ts +15 -15
  201. package/src/adapters/index.ts +1 -1
  202. package/src/constants/index.ts +4 -4
  203. package/src/core/Agent.ts +210 -206
  204. package/src/core/Events.ts +12 -12
  205. package/src/core/PersistenceManager.ts +32 -36
  206. package/src/core/ResponseEngine.ts +11 -17
  207. package/src/core/Route.ts +55 -49
  208. package/src/core/RoutingEngine.ts +244 -252
  209. package/src/core/Step.ts +197 -0
  210. package/src/core/ToolExecutor.ts +11 -11
  211. package/src/core/Transition.ts +72 -26
  212. package/src/index.ts +8 -8
  213. package/src/types/agent.ts +8 -8
  214. package/src/types/ai.ts +2 -2
  215. package/src/types/history.ts +3 -3
  216. package/src/types/index.ts +1 -1
  217. package/src/types/persistence.ts +6 -6
  218. package/src/types/route.ts +77 -61
  219. package/src/types/session.ts +75 -78
  220. package/src/types/tool.ts +17 -17
  221. package/src/utils/id.ts +15 -6
  222. package/dist/cjs/core/State.d.ts +0 -72
  223. package/dist/cjs/core/State.d.ts.map +0 -1
  224. package/dist/cjs/core/State.js +0 -148
  225. package/dist/cjs/core/State.js.map +0 -1
  226. package/dist/core/State.d.ts +0 -72
  227. package/dist/core/State.d.ts.map +0 -1
  228. package/dist/core/State.js +0 -144
  229. package/dist/core/State.js.map +0 -1
  230. package/docs/STATES.md +0 -888
  231. package/src/core/State.ts +0 -212
@@ -1,18 +1,18 @@
1
1
  /**
2
2
  * Core Agent implementation
3
3
  */
4
- import { createSession, enterRoute, enterState, mergeExtracted } from "../types/session";
4
+ import { createSession, enterRoute, enterStep, mergeCollected, } from "../types/session";
5
5
  import { PromptComposer } from "./PromptComposer";
6
6
  import { logger, LoggerLevel } from "../utils/logger";
7
7
  import { Route } from "./Route";
8
- import { State } from "./State";
8
+ import { Step } from "./Step";
9
9
  import { DomainRegistry } from "./DomainRegistry";
10
10
  import { PersistenceManager } from "./PersistenceManager";
11
11
  import { RoutingEngine } from "./RoutingEngine";
12
12
  import { ResponseEngine } from "./ResponseEngine";
13
13
  import { ToolExecutor } from "./ToolExecutor";
14
14
  import { getLastMessageFromHistory } from "../utils/event";
15
- import { END_STATE_ID } from "../constants";
15
+ import { END_ROUTE_ID } from "../constants";
16
16
  /**
17
17
  * Main Agent class with generic context support
18
18
  */
@@ -98,7 +98,7 @@ export class Agent {
98
98
  }
99
99
  /**
100
100
  * Create a new route (journey)
101
- * @template TExtracted - Type of data extracted throughout the route
101
+ * @template TData - Type of data collected throughout the route
102
102
  */
103
103
  createRoute(options) {
104
104
  const route = new Route(options);
@@ -175,23 +175,23 @@ export class Agent {
175
175
  }
176
176
  }
177
177
  /**
178
- * Update extracted data in session with lifecycle hook support
179
- * Triggers the onExtractedUpdate lifecycle hook if configured
178
+ * Update collected data in session with lifecycle hook support
179
+ * Triggers the onDataUpdate lifecycle hook if configured
180
180
  * @internal
181
181
  */
182
- async updateExtracted(session, extractedUpdate) {
183
- const previousExtracted = { ...session.extracted };
184
- // Merge new extracted data
185
- let newExtracted = {
186
- ...session.extracted,
187
- ...extractedUpdate,
182
+ async updateData(session, collectedUpdate) {
183
+ const previousCollected = { ...session.data };
184
+ // Merge new collected data
185
+ let newCollected = {
186
+ ...session.data,
187
+ ...collectedUpdate,
188
188
  };
189
189
  // Trigger lifecycle hook if configured
190
- if (this.options.hooks?.onExtractedUpdate) {
191
- newExtracted = (await this.options.hooks.onExtractedUpdate(newExtracted, previousExtracted));
190
+ if (this.options.hooks?.onDataUpdate) {
191
+ newCollected = (await this.options.hooks.onDataUpdate(newCollected, previousCollected));
192
192
  }
193
193
  // Return updated session
194
- return mergeExtracted(session, newExtracted);
194
+ return mergeCollected(session, newCollected);
195
195
  }
196
196
  /**
197
197
  * Get current context (fetches from provider if configured)
@@ -225,37 +225,37 @@ export class Agent {
225
225
  };
226
226
  // Initialize or get session (use current session if available)
227
227
  let session = params.session || this.currentSession || createSession();
228
- // PHASE 1: TOOL EXECUTION - Execute tools if current state has toolState
229
- if (session.currentRoute && session.currentState) {
228
+ // PHASE 1: TOOL EXECUTION - Execute tools if current step has tool
229
+ if (session.currentRoute && session.currentStep) {
230
230
  const currentRoute = this.routes.find((r) => r.id === session.currentRoute?.id);
231
231
  if (currentRoute) {
232
- const currentState = currentRoute.getState(session.currentState.id);
233
- if (currentState) {
234
- const transitions = currentState.getTransitions();
235
- const toolTransition = transitions.find((t) => t.spec.toolState);
236
- if (toolTransition?.spec.toolState) {
232
+ const currentStep = currentRoute.getStep(session.currentStep.id);
233
+ if (currentStep) {
234
+ const transitions = currentStep.getTransitions();
235
+ const toolTransition = transitions.find((t) => t.spec.tool);
236
+ if (toolTransition?.spec.tool) {
237
237
  const toolExecutor = new ToolExecutor();
238
238
  // Get allowed domains from current route for security enforcement
239
239
  const allowedDomains = currentRoute.getDomains();
240
- const result = await toolExecutor.executeTool(toolTransition.spec.toolState, effectiveContext, this.updateContext.bind(this), history, session.extracted, allowedDomains);
240
+ const result = await toolExecutor.executeTool(toolTransition.spec.tool, effectiveContext, this.updateContext.bind(this), history, session.data, allowedDomains);
241
241
  // Update context with tool results
242
242
  if (result.contextUpdate) {
243
243
  await this.updateContext(result.contextUpdate);
244
244
  }
245
- // Update extracted data with tool results
246
- if (result.extractedUpdate) {
247
- session = await this.updateExtracted(session, result.extractedUpdate);
248
- logger.debug(`[Agent] Tool updated extracted data:`, result.extractedUpdate);
245
+ // Update collected data with tool results
246
+ if (result.collectedUpdate) {
247
+ session = await this.updateData(session, result.collectedUpdate);
248
+ logger.debug(`[Agent] Tool updated collected data:`, result.collectedUpdate);
249
249
  }
250
250
  logger.debug(`[Agent] Executed tool: ${result.toolName} (success: ${result.success})`);
251
251
  }
252
252
  }
253
253
  }
254
254
  }
255
- // PHASE 2: ROUTING + STATE SELECTION - Determine which route and state to use (combined)
255
+ // PHASE 2: ROUTING + STEP SELECTION - Determine which route and step to use (combined)
256
256
  let selectedRoute;
257
257
  let responseDirectives;
258
- let selectedState;
258
+ let selectedStep;
259
259
  let isRouteComplete = false;
260
260
  // Check for pending transition from previous route completion
261
261
  if (session.pendingTransition) {
@@ -270,7 +270,7 @@ export class Agent {
270
270
  session = enterRoute(session, targetRoute.id, targetRoute.title);
271
271
  // Merge initial data if available
272
272
  if (targetRoute.initialData) {
273
- session = mergeExtracted(session, targetRoute.initialData);
273
+ session = mergeCollected(session, targetRoute.initialData);
274
274
  }
275
275
  selectedRoute = targetRoute;
276
276
  }
@@ -285,7 +285,7 @@ export class Agent {
285
285
  }
286
286
  // If no pending transition or transition handled, do normal routing
287
287
  if (this.routes.length > 0 && !selectedRoute) {
288
- const orchestration = await this.routingEngine.decideRouteAndState({
288
+ const orchestration = await this.routingEngine.decideRouteAndStep({
289
289
  routes: this.routes,
290
290
  session,
291
291
  history,
@@ -300,45 +300,45 @@ export class Agent {
300
300
  signal,
301
301
  });
302
302
  selectedRoute = orchestration.selectedRoute;
303
- selectedState = orchestration.selectedState;
303
+ selectedStep = orchestration.selectedStep;
304
304
  responseDirectives = orchestration.responseDirectives;
305
305
  session = orchestration.session;
306
306
  isRouteComplete = orchestration.isRouteComplete || false;
307
307
  // Log if route is complete
308
308
  if (isRouteComplete) {
309
- logger.debug(`[Agent] Route complete: all required data collected, END_STATE reached`);
309
+ logger.debug(`[Agent] Route complete: all required data collected, END_ROUTE reached`);
310
310
  }
311
311
  }
312
- // PHASE 3: DETERMINE NEXT STATE - Use state from combined decision or get initial state
312
+ // PHASE 3: DETERMINE NEXT STEP - Use step from combined decision or get initial step
313
313
  if (selectedRoute && !isRouteComplete) {
314
- let nextState;
315
- // If we have a selected state from the combined routing decision, use it
316
- if (selectedState) {
317
- nextState = selectedState;
314
+ let nextStep;
315
+ // If we have a selected step from the combined routing decision, use it
316
+ if (selectedStep) {
317
+ nextStep = selectedStep;
318
318
  }
319
319
  else {
320
- // New route or no state selected - get initial state or first valid state
321
- const candidates = this.routingEngine.getCandidateStates(selectedRoute, undefined, session.extracted || {});
320
+ // New route or no step selected - get initial step or first valid step
321
+ const candidates = this.routingEngine.getCandidateSteps(selectedRoute, undefined, session.data || {});
322
322
  if (candidates.length > 0) {
323
- nextState = candidates[0].state;
324
- logger.debug(`[Agent] Using first valid state: ${nextState.id} for new route`);
323
+ nextStep = candidates[0].step;
324
+ logger.debug(`[Agent] Using first valid step: ${nextStep.id} for new route`);
325
325
  }
326
326
  else {
327
- // Fallback to initial state even if it should be skipped
328
- nextState = selectedRoute.initialState;
329
- logger.warn(`[Agent] No valid states found, using initial state: ${nextState.id}`);
327
+ // Fallback to initial step even if it should be skipped
328
+ nextStep = selectedRoute.initialStep;
329
+ logger.warn(`[Agent] No valid steps found, using initial step: ${nextStep.id}`);
330
330
  }
331
331
  }
332
- // Update session with next state
333
- session = enterState(session, nextState.id, nextState.description);
334
- logger.debug(`[Agent] Entered state: ${nextState.id}`);
335
- // PHASE 4: RESPONSE GENERATION - Stream message using selected route and state
332
+ // Update session with next step
333
+ session = enterStep(session, nextStep.id, nextStep.description);
334
+ logger.debug(`[Agent] Entered step: ${nextStep.id}`);
335
+ // PHASE 4: RESPONSE GENERATION - Stream message using selected route and step
336
336
  // Get last user message
337
337
  const lastUserMessage = getLastMessageFromHistory(history);
338
- // Build response schema for this route (with gather fields from state)
339
- const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextState);
338
+ // Build response schema for this route (with collect fields from step)
339
+ const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextStep);
340
340
  // Build response prompt
341
- const responsePrompt = this.responseEngine.buildResponsePrompt(selectedRoute, nextState, selectedRoute.getRules(), selectedRoute.getProhibitions(), responseDirectives, history, lastUserMessage, {
341
+ const responsePrompt = this.responseEngine.buildResponsePrompt(selectedRoute, nextStep, selectedRoute.getRules(), selectedRoute.getProhibitions(), responseDirectives, history, lastUserMessage, {
342
342
  name: this.options.name,
343
343
  goal: this.options.goal,
344
344
  description: this.options.description,
@@ -358,20 +358,20 @@ export class Agent {
358
358
  // Stream chunks to caller
359
359
  for await (const chunk of stream) {
360
360
  const toolCalls = undefined;
361
- // Extract gathered data on final chunk
362
- if (chunk.done && chunk.structured && nextState.gatherFields) {
363
- const gatheredData = {};
364
- // The structured response includes both base fields and gathered extraction fields
361
+ // Extract collected data on final chunk
362
+ if (chunk.done && chunk.structured && nextStep.collectFields) {
363
+ const collectedData = {};
364
+ // The structured response includes both base fields and collected extraction fields
365
365
  const structuredData = chunk.structured;
366
- for (const field of nextState.gatherFields) {
366
+ for (const field of nextStep.collectFields) {
367
367
  if (field in structuredData) {
368
- gatheredData[field] = structuredData[field];
368
+ collectedData[field] = structuredData[field];
369
369
  }
370
370
  }
371
- // Merge gathered data into session
372
- if (Object.keys(gatheredData).length > 0) {
373
- session = await this.updateExtracted(session, gatheredData);
374
- logger.debug(`[Agent] Extracted data:`, gatheredData);
371
+ // Merge collected data into session
372
+ if (Object.keys(collectedData).length > 0) {
373
+ session = await this.updateData(session, collectedData);
374
+ logger.debug(`[Agent] Collected data:`, collectedData);
375
375
  }
376
376
  }
377
377
  // Extract any additional data from structured response on final chunk
@@ -382,13 +382,13 @@ export class Agent {
382
382
  await this.updateContext(chunk.structured
383
383
  .contextUpdate);
384
384
  }
385
- // Auto-save session state on final chunk
385
+ // Auto-save session step on final chunk
386
386
  if (chunk.done &&
387
387
  this.persistenceManager &&
388
388
  session.id &&
389
389
  this.options.persistence?.autoSave !== false) {
390
- await this.persistenceManager.saveSessionState(session.id, session);
391
- logger.debug(`[Agent] Auto-saved session state to persistence: ${session.id}`);
390
+ await this.persistenceManager.saveSessionStep(session.id, session);
391
+ logger.debug(`[Agent] Auto-saved session step to persistence: ${session.id}`);
392
392
  }
393
393
  // Update current session if we have one
394
394
  if (chunk.done && this.currentSession) {
@@ -407,14 +407,16 @@ export class Agent {
407
407
  else if (isRouteComplete && selectedRoute) {
408
408
  // Route is complete - generate completion message then check for onComplete transition
409
409
  const lastUserMessage = getLastMessageFromHistory(history);
410
- // Get endState spec from route
411
- const endStateSpec = selectedRoute.endStateSpec;
412
- // Create a temporary state for completion message generation using endState configuration
413
- const completionState = new State(selectedRoute.id, endStateSpec.chatState || "Summarize what was accomplished and confirm completion", endStateSpec.id || END_STATE_ID, endStateSpec.gather, undefined, endStateSpec.requiredData, endStateSpec.chatState || "Summarize what was accomplished and confirm completion based on the conversation history and collected data");
410
+ // Get endStep spec from route
411
+ const endStepSpec = selectedRoute.endStepSpec;
412
+ // Create a temporary step for completion message generation using endStep configuration
413
+ const completionStep = new Step(selectedRoute.id, endStepSpec.instructions ||
414
+ "Summarize what was accomplished and confirm completion", endStepSpec.id || END_ROUTE_ID, endStepSpec.collect, undefined, endStepSpec.requires, endStepSpec.instructions ||
415
+ "Summarize what was accomplished and confirm completion based on the conversation history and collected data");
414
416
  // Build response schema for completion
415
- const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionState);
417
+ const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionStep);
416
418
  // Build completion response prompt
417
- const completionPrompt = this.responseEngine.buildResponsePrompt(selectedRoute, completionState, selectedRoute.getRules(), selectedRoute.getProhibitions(), undefined, // No directives for completion
419
+ const completionPrompt = this.responseEngine.buildResponsePrompt(selectedRoute, completionStep, selectedRoute.getRules(), selectedRoute.getProhibitions(), undefined, // No directives for completion
418
420
  history, lastUserMessage, {
419
421
  name: this.options.name,
420
422
  goal: this.options.goal,
@@ -434,11 +436,11 @@ export class Agent {
434
436
  });
435
437
  logger.debug(`[Agent] Streaming completion message for route: ${selectedRoute.title}`);
436
438
  // Check for onComplete transition
437
- const transitionConfig = await selectedRoute.evaluateOnComplete({ extracted: session.extracted }, effectiveContext);
439
+ const transitionConfig = await selectedRoute.evaluateOnComplete({ data: session.data }, effectiveContext);
438
440
  if (transitionConfig) {
439
441
  // Find target route by ID or title
440
- const targetRoute = this.routes.find((r) => r.id === transitionConfig.transitionTo ||
441
- r.title === transitionConfig.transitionTo);
442
+ const targetRoute = this.routes.find((r) => r.id === transitionConfig.nextStep ||
443
+ r.title === transitionConfig.nextStep);
442
444
  if (targetRoute) {
443
445
  // Set pending transition in session
444
446
  session = {
@@ -452,12 +454,12 @@ export class Agent {
452
454
  logger.debug(`[Agent] Route ${selectedRoute.title} completed with pending transition to: ${targetRoute.title}`);
453
455
  }
454
456
  else {
455
- logger.warn(`[Agent] Route ${selectedRoute.title} completed but target route not found: ${transitionConfig.transitionTo}`);
457
+ logger.warn(`[Agent] Route ${selectedRoute.title} completed but target route not found: ${transitionConfig.nextStep}`);
456
458
  }
457
459
  }
458
- // Set state to END_STATE marker
459
- session = enterState(session, END_STATE_ID, "Route completed");
460
- logger.debug(`[Agent] Route ${selectedRoute.title} completed. Entered END_STATE state.`);
460
+ // Set step to END_ROUTE marker
461
+ session = enterStep(session, END_ROUTE_ID, "Route completed");
462
+ logger.debug(`[Agent] Route ${selectedRoute.title} completed. Entered END_ROUTE step.`);
461
463
  // Stream completion chunks
462
464
  for await (const chunk of stream) {
463
465
  // Update current session if we have one
@@ -541,37 +543,37 @@ export class Agent {
541
543
  };
542
544
  // Initialize or get session (use current session if available)
543
545
  let session = params.session || this.currentSession || createSession();
544
- // PHASE 1: TOOL EXECUTION - Execute tools if current state has toolState
545
- if (session.currentRoute && session.currentState) {
546
+ // PHASE 1: TOOL EXECUTION - Execute tools if current step has tool
547
+ if (session.currentRoute && session.currentStep) {
546
548
  const currentRoute = this.routes.find((r) => r.id === session.currentRoute?.id);
547
549
  if (currentRoute) {
548
- const currentState = currentRoute.getState(session.currentState.id);
549
- if (currentState) {
550
- const transitions = currentState.getTransitions();
551
- const toolTransition = transitions.find((t) => t.spec.toolState);
552
- if (toolTransition?.spec.toolState) {
550
+ const currentStep = currentRoute.getStep(session.currentStep.id);
551
+ if (currentStep) {
552
+ const transitions = currentStep.getTransitions();
553
+ const toolTransition = transitions.find((t) => t.spec.tool);
554
+ if (toolTransition?.spec.tool) {
553
555
  const toolExecutor = new ToolExecutor();
554
556
  // Get allowed domains from current route for security enforcement
555
557
  const allowedDomains = currentRoute.getDomains();
556
- const result = await toolExecutor.executeTool(toolTransition.spec.toolState, effectiveContext, this.updateContext.bind(this), history, session.extracted, allowedDomains);
558
+ const result = await toolExecutor.executeTool(toolTransition.spec.tool, effectiveContext, this.updateContext.bind(this), history, session.data, allowedDomains);
557
559
  // Update context with tool results
558
560
  if (result.contextUpdate) {
559
561
  await this.updateContext(result.contextUpdate);
560
562
  }
561
- // Update extracted data with tool results
562
- if (result.extractedUpdate) {
563
- session = await this.updateExtracted(session, result.extractedUpdate);
564
- logger.debug(`[Agent] Tool updated extracted data:`, result.extractedUpdate);
563
+ // Update collected data with tool results
564
+ if (result.collectedUpdate) {
565
+ session = await this.updateData(session, result.collectedUpdate);
566
+ logger.debug(`[Agent] Tool updated collected data:`, result.collectedUpdate);
565
567
  }
566
568
  logger.debug(`[Agent] Executed tool: ${result.toolName} (success: ${result.success})`);
567
569
  }
568
570
  }
569
571
  }
570
572
  }
571
- // PHASE 2: ROUTING + STATE SELECTION - Determine which route and state to use (combined)
573
+ // PHASE 2: ROUTING + STEP SELECTION - Determine which route and step to use (combined)
572
574
  let selectedRoute;
573
575
  let responseDirectives;
574
- let selectedState;
576
+ let selectedStep;
575
577
  let isRouteComplete = false;
576
578
  // Check for pending transition from previous route completion
577
579
  if (session.pendingTransition) {
@@ -586,7 +588,7 @@ export class Agent {
586
588
  session = enterRoute(session, targetRoute.id, targetRoute.title);
587
589
  // Merge initial data if available
588
590
  if (targetRoute.initialData) {
589
- session = mergeExtracted(session, targetRoute.initialData);
591
+ session = mergeCollected(session, targetRoute.initialData);
590
592
  }
591
593
  selectedRoute = targetRoute;
592
594
  }
@@ -601,7 +603,7 @@ export class Agent {
601
603
  }
602
604
  // If no pending transition or transition handled, do normal routing
603
605
  if (this.routes.length > 0 && !selectedRoute) {
604
- const orchestration = await this.routingEngine.decideRouteAndState({
606
+ const orchestration = await this.routingEngine.decideRouteAndStep({
605
607
  routes: this.routes,
606
608
  session,
607
609
  history,
@@ -616,47 +618,47 @@ export class Agent {
616
618
  signal,
617
619
  });
618
620
  selectedRoute = orchestration.selectedRoute;
619
- selectedState = orchestration.selectedState;
621
+ selectedStep = orchestration.selectedStep;
620
622
  responseDirectives = orchestration.responseDirectives;
621
623
  session = orchestration.session;
622
624
  isRouteComplete = orchestration.isRouteComplete || false;
623
625
  // Log if route is complete
624
626
  if (isRouteComplete) {
625
- logger.debug(`[Agent] Route complete: all required data collected, END_STATE reached`);
627
+ logger.debug(`[Agent] Route complete: all required data collected, END_ROUTE reached`);
626
628
  }
627
629
  }
628
- // PHASE 3: DETERMINE NEXT STATE - Use state from combined decision or get initial state
630
+ // PHASE 3: DETERMINE NEXT STEP - Use step from combined decision or get initial step
629
631
  let message;
630
632
  const toolCalls = undefined;
631
633
  if (selectedRoute && !isRouteComplete) {
632
- let nextState;
633
- // If we have a selected state from the combined routing decision, use it
634
- if (selectedState) {
635
- nextState = selectedState;
634
+ let nextStep;
635
+ // If we have a selected step from the combined routing decision, use it
636
+ if (selectedStep) {
637
+ nextStep = selectedStep;
636
638
  }
637
639
  else {
638
- // New route or no state selected - get initial state or first valid state
639
- const candidates = this.routingEngine.getCandidateStates(selectedRoute, undefined, session.extracted || {});
640
+ // New route or no step selected - get initial step or first valid step
641
+ const candidates = this.routingEngine.getCandidateSteps(selectedRoute, undefined, session.data || {});
640
642
  if (candidates.length > 0) {
641
- nextState = candidates[0].state;
642
- logger.debug(`[Agent] Using first valid state: ${nextState.id} for new route`);
643
+ nextStep = candidates[0].step;
644
+ logger.debug(`[Agent] Using first valid step: ${nextStep.id} for new route`);
643
645
  }
644
646
  else {
645
- // Fallback to initial state even if it should be skipped
646
- nextState = selectedRoute.initialState;
647
- logger.warn(`[Agent] No valid states found, using initial state: ${nextState.id}`);
647
+ // Fallback to initial step even if it should be skipped
648
+ nextStep = selectedRoute.initialStep;
649
+ logger.warn(`[Agent] No valid steps found, using initial step: ${nextStep.id}`);
648
650
  }
649
651
  }
650
- // Update session with next state
651
- session = enterState(session, nextState.id, nextState.description);
652
- logger.debug(`[Agent] Entered state: ${nextState.id}`);
653
- // PHASE 4: RESPONSE GENERATION - Generate message using selected route and state
652
+ // Update session with next step
653
+ session = enterStep(session, nextStep.id, nextStep.description);
654
+ logger.debug(`[Agent] Entered step: ${nextStep.id}`);
655
+ // PHASE 4: RESPONSE GENERATION - Generate message using selected route and step
654
656
  // Get last user message
655
657
  const lastUserMessage = getLastMessageFromHistory(history);
656
- // Build response schema for this route (with gather fields from state)
657
- const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextState);
658
+ // Build response schema for this route (with collect fields from step)
659
+ const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextStep);
658
660
  // Build response prompt
659
- const responsePrompt = this.responseEngine.buildResponsePrompt(selectedRoute, nextState, selectedRoute.getRules(), selectedRoute.getProhibitions(), responseDirectives, history, lastUserMessage, {
661
+ const responsePrompt = this.responseEngine.buildResponsePrompt(selectedRoute, nextStep, selectedRoute.getRules(), selectedRoute.getProhibitions(), responseDirectives, history, lastUserMessage, {
660
662
  name: this.options.name,
661
663
  goal: this.options.goal,
662
664
  description: this.options.description,
@@ -674,20 +676,20 @@ export class Agent {
674
676
  },
675
677
  });
676
678
  message = result.structured?.message || result.message;
677
- // Extract gathered data from response
678
- if (result.structured && nextState.gatherFields) {
679
- const gatheredData = {};
680
- // The structured response includes both base fields and gathered extraction fields
679
+ // Extract collected data from response
680
+ if (result.structured && nextStep.collectFields) {
681
+ const collectedData = {};
682
+ // The structured response includes both base fields and collected extraction fields
681
683
  const structuredData = result.structured;
682
- for (const field of nextState.gatherFields) {
684
+ for (const field of nextStep.collectFields) {
683
685
  if (field in structuredData) {
684
- gatheredData[field] = structuredData[field];
686
+ collectedData[field] = structuredData[field];
685
687
  }
686
688
  }
687
- // Merge gathered data into session
688
- if (Object.keys(gatheredData).length > 0) {
689
- session = await this.updateExtracted(session, gatheredData);
690
- logger.debug(`[Agent] Extracted data:`, gatheredData);
689
+ // Merge collected data into session
690
+ if (Object.keys(collectedData).length > 0) {
691
+ session = await this.updateData(session, collectedData);
692
+ logger.debug(`[Agent] Collected data:`, collectedData);
691
693
  }
692
694
  }
693
695
  // Extract any additional data from structured response
@@ -701,14 +703,16 @@ export class Agent {
701
703
  else if (isRouteComplete && selectedRoute) {
702
704
  // Route is complete - generate completion message then check for onComplete transition
703
705
  const lastUserMessage = getLastMessageFromHistory(history);
704
- // Get endState spec from route
705
- const endStateSpec = selectedRoute.endStateSpec;
706
- // Create a temporary state for completion message generation using endState configuration
707
- const completionState = new State(selectedRoute.id, endStateSpec.chatState || "Summarize what was accomplished and confirm completion", endStateSpec.id || END_STATE_ID, endStateSpec.gather, undefined, endStateSpec.requiredData, endStateSpec.chatState || "Summarize what was accomplished and confirm completion based on the conversation history and collected data");
706
+ // Get endStep spec from route
707
+ const endStepSpec = selectedRoute.endStepSpec;
708
+ // Create a temporary step for completion message generation using endStep configuration
709
+ const completionStep = new Step(selectedRoute.id, endStepSpec.instructions ||
710
+ "Summarize what was accomplished and confirm completion", endStepSpec.id || END_ROUTE_ID, endStepSpec.collect, undefined, endStepSpec.requires, endStepSpec.instructions ||
711
+ "Summarize what was accomplished and confirm completion based on the conversation history and collected data");
708
712
  // Build response schema for completion
709
- const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionState);
713
+ const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionStep);
710
714
  // Build completion response prompt
711
- const completionPrompt = this.responseEngine.buildResponsePrompt(selectedRoute, completionState, selectedRoute.getRules(), selectedRoute.getProhibitions(), undefined, // No directives for completion
715
+ const completionPrompt = this.responseEngine.buildResponsePrompt(selectedRoute, completionStep, selectedRoute.getRules(), selectedRoute.getProhibitions(), undefined, // No directives for completion
712
716
  history, lastUserMessage, {
713
717
  name: this.options.name,
714
718
  goal: this.options.goal,
@@ -726,14 +730,15 @@ export class Agent {
726
730
  schemaName: "completion_message",
727
731
  },
728
732
  });
729
- message = completionResult.structured?.message || completionResult.message;
733
+ message =
734
+ completionResult.structured?.message || completionResult.message;
730
735
  logger.debug(`[Agent] Generated completion message for route: ${selectedRoute.title}`);
731
736
  // Check for onComplete transition
732
- const transitionConfig = await selectedRoute.evaluateOnComplete({ extracted: session.extracted }, effectiveContext);
737
+ const transitionConfig = await selectedRoute.evaluateOnComplete({ data: session.data }, effectiveContext);
733
738
  if (transitionConfig) {
734
739
  // Find target route by ID or title
735
- const targetRoute = this.routes.find((r) => r.id === transitionConfig.transitionTo ||
736
- r.title === transitionConfig.transitionTo);
740
+ const targetRoute = this.routes.find((r) => r.id === transitionConfig.nextStep ||
741
+ r.title === transitionConfig.nextStep);
737
742
  if (targetRoute) {
738
743
  // Set pending transition in session
739
744
  session = {
@@ -747,12 +752,12 @@ export class Agent {
747
752
  logger.debug(`[Agent] Route ${selectedRoute.title} completed with pending transition to: ${targetRoute.title}`);
748
753
  }
749
754
  else {
750
- logger.warn(`[Agent] Route ${selectedRoute.title} completed but target route not found: ${transitionConfig.transitionTo}`);
755
+ logger.warn(`[Agent] Route ${selectedRoute.title} completed but target route not found: ${transitionConfig.nextStep}`);
751
756
  }
752
757
  }
753
- // Set state to END_STATE marker
754
- session = enterState(session, END_STATE_ID, "Route completed");
755
- logger.debug(`[Agent] Route ${selectedRoute.title} completed. Entered END_STATE state.`);
758
+ // Set step to END_ROUTE marker
759
+ session = enterStep(session, END_ROUTE_ID, "Route completed");
760
+ logger.debug(`[Agent] Route ${selectedRoute.title} completed. Entered END_ROUTE step.`);
756
761
  }
757
762
  else {
758
763
  // Fallback: No routes defined, generate a simple response
@@ -787,12 +792,12 @@ export class Agent {
787
792
  });
788
793
  message = result.structured?.message || result.message;
789
794
  }
790
- // Auto-save session state to persistence if configured
795
+ // Auto-save session step to persistence if configured
791
796
  if (this.persistenceManager &&
792
797
  session.id &&
793
798
  this.options.persistence?.autoSave !== false) {
794
- await this.persistenceManager.saveSessionState(session.id, session);
795
- logger.debug(`[Agent] Auto-saved session state to persistence: ${session.id}`);
799
+ await this.persistenceManager.saveSessionStep(session.id, session);
800
+ logger.debug(`[Agent] Auto-saved session step to persistence: ${session.id}`);
796
801
  }
797
802
  // Update current session if we have one
798
803
  if (this.currentSession) {
@@ -800,9 +805,9 @@ export class Agent {
800
805
  }
801
806
  return {
802
807
  message,
803
- session, // Return updated session with route/state info
808
+ session, // Return updated session with route/step info
804
809
  toolCalls,
805
- isRouteComplete, // Indicates if the route has reached END_STATE with all data collected
810
+ isRouteComplete, // Indicates if the route has reached END_ROUTE with all data collected
806
811
  };
807
812
  }
808
813
  /**
@@ -877,7 +882,7 @@ export class Agent {
877
882
  }
878
883
  /**
879
884
  * Set the current session for convenience methods
880
- * @param session - Session state to use for subsequent calls
885
+ * @param session - Session step to use for subsequent calls
881
886
  */
882
887
  setCurrentSession(session) {
883
888
  this.currentSession = session;
@@ -895,37 +900,38 @@ export class Agent {
895
900
  this.currentSession = undefined;
896
901
  }
897
902
  /**
898
- * Get extracted data from current session
903
+ * Get collected data from current session
899
904
  * @param routeId - Optional route ID to get data for (uses current route if not provided)
900
- * @returns The extracted data from the current session
905
+ * @returns The collected data from the current session
901
906
  */
902
- getExtractedData(routeId) {
907
+ getData(routeId) {
903
908
  if (!this.currentSession) {
904
909
  return {};
905
910
  }
906
911
  if (routeId) {
907
- return (this.currentSession.extractedByRoute?.[routeId] || {});
912
+ return (this.currentSession.dataByRoute?.[routeId] ||
913
+ {});
908
914
  }
909
- return this.currentSession.extracted || {};
915
+ return this.currentSession.data || {};
910
916
  }
911
917
  /**
912
918
  * Manually transition to a different route
913
919
  * Sets a pending transition that will be executed on the next respond() call
914
920
  *
915
921
  * @param routeIdOrTitle - Route ID or title to transition to
916
- * @param session - Session state to update (uses current session if not provided)
922
+ * @param session - Session step to update (uses current session if not provided)
917
923
  * @param condition - Optional AI-evaluated condition for the transition
918
924
  * @returns Updated session with pending transition
919
925
  *
920
926
  * @example
921
927
  * // After route completes
922
928
  * if (response.isRouteComplete && response.session) {
923
- * const updatedSession = agent.transitionToRoute("feedback-collection", response.session);
929
+ * const updatedSession = agent.nextStepRoute("feedback-collection", response.session);
924
930
  * // Next respond() call will automatically transition to feedback route
925
931
  * const nextResponse = await agent.respond({ history, session: updatedSession });
926
932
  * }
927
933
  */
928
- transitionToRoute(routeIdOrTitle, session, condition) {
934
+ nextStepRoute(routeIdOrTitle, session, condition) {
929
935
  const targetSession = session || this.currentSession;
930
936
  if (!targetSession) {
931
937
  throw new Error("No session provided and no current session available. Please provide a session to transition.");
@@ -933,7 +939,9 @@ export class Agent {
933
939
  // Find target route by ID or title
934
940
  const targetRoute = this.routes.find((r) => r.id === routeIdOrTitle || r.title === routeIdOrTitle);
935
941
  if (!targetRoute) {
936
- throw new Error(`Route not found: ${routeIdOrTitle}. Available routes: ${this.routes.map((r) => r.title).join(", ")}`);
942
+ throw new Error(`Route not found: ${routeIdOrTitle}. Available routes: ${this.routes
943
+ .map((r) => r.title)
944
+ .join(", ")}`);
937
945
  }
938
946
  const updatedSession = {
939
947
  ...targetSession,