@falai/agent 0.6.8 → 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
@@ -11,10 +11,10 @@ class RoutingEngine {
11
11
  }
12
12
  /**
13
13
  * Optimized decision for single-route scenarios
14
- * Skips route scoring and only does state selection
14
+ * Skips route scoring and only does step selection
15
15
  * @private
16
16
  */
17
- async decideSingleRouteState(params) {
17
+ async decideSingleRouteStep(params) {
18
18
  const { route, session, history, agentMeta, ai, context, signal } = params;
19
19
  let updatedSession = session;
20
20
  const selectedRoute = route;
@@ -22,237 +22,237 @@ class RoutingEngine {
22
22
  if (!session.currentRoute || session.currentRoute.id !== route.id) {
23
23
  updatedSession = (0, session_1.enterRoute)(session, route.id, route.title);
24
24
  if (route.initialData) {
25
- updatedSession = (0, session_1.mergeExtracted)(updatedSession, route.initialData);
25
+ updatedSession = (0, session_1.mergeCollected)(updatedSession, route.initialData);
26
26
  logger_1.logger.debug(`[RoutingEngine] Single-route: Merged initial data:`, route.initialData);
27
27
  }
28
28
  logger_1.logger.debug(`[RoutingEngine] Single-route: Entered route: ${route.title}`);
29
29
  }
30
- // Get candidate states
31
- const currentState = updatedSession.currentState
32
- ? route.getState(updatedSession.currentState.id)
30
+ // Get candidate steps
31
+ const currentStep = updatedSession.currentStep
32
+ ? route.getStep(updatedSession.currentStep.id)
33
33
  : undefined;
34
- const candidates = this.getCandidateStates(route, currentState, updatedSession.extracted || {});
34
+ const candidates = this.getCandidateSteps(route, currentStep, updatedSession.data || {});
35
35
  if (candidates.length === 0) {
36
- logger_1.logger.warn(`[RoutingEngine] Single-route: No valid states found`);
36
+ logger_1.logger.warn(`[RoutingEngine] Single-route: No valid steps found`);
37
37
  return { selectedRoute, session: updatedSession };
38
38
  }
39
39
  // If only one candidate, check if route is complete
40
40
  if (candidates.length === 1) {
41
41
  const isRouteComplete = candidates[0].isRouteComplete;
42
42
  if (isRouteComplete) {
43
- logger_1.logger.debug(`[RoutingEngine] Single-route: Route complete - all data collected, END_STATE reached`);
44
- // Don't return a selectedState when route is complete - there's no state to enter
43
+ logger_1.logger.debug(`[RoutingEngine] Single-route: Route complete - all data collected, END_ROUTE reached`);
44
+ // Don't return a selectedStep when route is complete - there's no step to enter
45
45
  return {
46
46
  selectedRoute,
47
- selectedState: undefined,
47
+ selectedStep: undefined,
48
48
  session: updatedSession,
49
49
  isRouteComplete: true,
50
50
  };
51
51
  }
52
52
  else {
53
- logger_1.logger.debug(`[RoutingEngine] Single-route: Only one valid state: ${candidates[0].state.id}`);
53
+ logger_1.logger.debug(`[RoutingEngine] Single-route: Only one valid step: ${candidates[0].step.id}`);
54
54
  return {
55
55
  selectedRoute,
56
- selectedState: candidates[0].state,
56
+ selectedStep: candidates[0].step,
57
57
  session: updatedSession,
58
58
  isRouteComplete: false,
59
59
  };
60
60
  }
61
61
  }
62
- // Multiple candidates - use AI to select best state
62
+ // Multiple candidates - use AI to select best step
63
63
  const lastUserMessage = (0, event_1.getLastMessageFromHistory)(history);
64
- const statePrompt = this.buildStateSelectionPrompt(route, currentState, candidates, updatedSession.extracted || {}, history, lastUserMessage, agentMeta);
65
- const stateSchema = this.buildStateSelectionSchema(candidates.map((c) => c.state.id));
66
- const stateResult = await ai.generateMessage({
67
- prompt: statePrompt,
64
+ const stepPrompt = this.buildStepSelectionPrompt(route, currentStep, candidates, updatedSession.data || {}, history, lastUserMessage, agentMeta);
65
+ const stepSchema = this.buildStepSelectionSchema(candidates.map((c) => c.step.id));
66
+ const stepResult = await ai.generateMessage({
67
+ prompt: stepPrompt,
68
68
  history,
69
69
  context,
70
70
  signal,
71
71
  parameters: {
72
- jsonSchema: stateSchema,
73
- schemaName: "state_selection",
72
+ jsonSchema: stepSchema,
73
+ schemaName: "step_selection",
74
74
  },
75
75
  });
76
- const selectedStateId = stateResult.structured?.selectedStateId;
77
- const selectedState = candidates.find((c) => c.state.id === selectedStateId)?.state;
78
- if (selectedState) {
79
- logger_1.logger.debug(`[RoutingEngine] Single-route: AI selected state: ${selectedState.id}`);
80
- logger_1.logger.debug(`[RoutingEngine] Single-route: Reasoning: ${stateResult.structured?.reasoning}`);
76
+ const selectedStepId = stepResult.structured?.selectedStepId;
77
+ const selectedStep = candidates.find((c) => c.step.id === selectedStepId)?.step;
78
+ if (selectedStep) {
79
+ logger_1.logger.debug(`[RoutingEngine] Single-route: AI selected step: ${selectedStep.id}`);
80
+ logger_1.logger.debug(`[RoutingEngine] Single-route: Reasoning: ${stepResult.structured?.reasoning}`);
81
81
  }
82
82
  else {
83
- logger_1.logger.warn(`[RoutingEngine] Single-route: Invalid state ID returned, using first candidate`);
83
+ logger_1.logger.warn(`[RoutingEngine] Single-route: Invalid step ID returned, using first candidate`);
84
84
  }
85
85
  return {
86
86
  selectedRoute,
87
- selectedState: selectedState || candidates[0].state,
88
- responseDirectives: stateResult.structured?.responseDirectives,
87
+ selectedStep: selectedStep || candidates[0].step,
88
+ responseDirectives: stepResult.structured?.responseDirectives,
89
89
  session: updatedSession,
90
90
  };
91
91
  }
92
92
  /**
93
- * Recursively traverse state chain to find first non-skipped state or END_STATE
93
+ * Recursively traverse step chain to find first non-skipped step or END_ROUTE
94
94
  * @private
95
95
  */
96
- findFirstValidStateRecursive(currentState, extracted, visited) {
96
+ findFirstValidStepRecursive(currentStep, data, visited) {
97
97
  // Prevent infinite loops
98
- if (visited.has(currentState.id)) {
98
+ if (visited.has(currentStep.id)) {
99
99
  return {};
100
100
  }
101
- visited.add(currentState.id);
102
- const transitions = currentState.getTransitions();
101
+ visited.add(currentStep.id);
102
+ const transitions = currentStep.getTransitions();
103
103
  for (const transition of transitions) {
104
104
  const target = transition.getTarget();
105
- // Check for END_STATE transition
105
+ // Check for END_ROUTE transition
106
106
  if (!target &&
107
- transition.spec.state &&
108
- typeof transition.spec.state === "symbol") {
109
- // Found END_STATE - route is complete
107
+ transition.spec.step &&
108
+ typeof transition.spec.step === "symbol") {
109
+ // Found END_ROUTE - route is complete
110
110
  return {
111
- isRouteComplete: true
111
+ isRouteComplete: true,
112
112
  };
113
113
  }
114
114
  if (!target)
115
115
  continue;
116
- // If target should NOT be skipped, we found our state
117
- if (!target.shouldSkip(extracted)) {
118
- logger_1.logger.debug(`[RoutingEngine] Found valid state after skipping: ${target.id}`);
116
+ // If target should NOT be skipped, we found our step
117
+ if (!target.shouldSkip(data)) {
118
+ logger_1.logger.debug(`[RoutingEngine] Found valid step after skipping: ${target.id}`);
119
119
  return {
120
- state: target,
120
+ step: target,
121
121
  condition: transition.condition,
122
122
  };
123
123
  }
124
124
  // Target should be skipped too - recurse deeper
125
- logger_1.logger.debug(`[RoutingEngine] Skipping state ${target.id} (skipIf condition met), continuing traversal...`);
126
- const result = this.findFirstValidStateRecursive(target, extracted, visited);
127
- // If we found something (a valid state or END_STATE), return it
128
- if (result.state || result.isRouteComplete) {
125
+ logger_1.logger.debug(`[RoutingEngine] Skipping step ${target.id} (skipIf condition met), continuing traversal...`);
126
+ const result = this.findFirstValidStepRecursive(target, data, visited);
127
+ // If we found something (a valid step or END_ROUTE), return it
128
+ if (result.step || result.isRouteComplete) {
129
129
  return result;
130
130
  }
131
131
  }
132
- // No valid states or END_STATE found in this branch
132
+ // No valid steps or END_ROUTE found in this branch
133
133
  return {};
134
134
  }
135
135
  /**
136
- * Identify valid next candidate states based on current state and extracted data
137
- * Returns state with isRouteComplete flag if route is complete (all states skipped + has END_STATE transition)
136
+ * Identify valid next candidate steps based on current step and collected data
137
+ * Returns step with isRouteComplete flag if route is complete (all steps skipped + has END_ROUTE transition)
138
138
  */
139
- getCandidateStates(route, currentState, extracted) {
139
+ getCandidateSteps(route, currentStep, data) {
140
140
  const candidates = [];
141
- if (!currentState) {
142
- const initialState = route.initialState;
143
- if (initialState.shouldSkip(extracted)) {
144
- // Initial state should be skipped - recursively traverse to find first non-skipped state or END_STATE
145
- const result = this.findFirstValidStateRecursive(initialState, extracted, new Set());
141
+ if (!currentStep) {
142
+ const initialStep = route.initialStep;
143
+ if (initialStep.shouldSkip(data)) {
144
+ // Initial step should be skipped - recursively traverse to find first non-skipped step or END_ROUTE
145
+ const result = this.findFirstValidStepRecursive(initialStep, data, new Set());
146
146
  if (result.isRouteComplete) {
147
- // All states are skipped and we reached END_STATE
148
- logger_1.logger.debug(`[RoutingEngine] Route complete on entry: all states skipped, END_STATE reached`);
147
+ // All steps are skipped and we reached END_ROUTE
148
+ logger_1.logger.debug(`[RoutingEngine] Route complete on entry: all steps skipped, END_ROUTE reached`);
149
149
  return [
150
150
  {
151
- state: initialState,
151
+ step: initialStep,
152
152
  condition: "Route complete - all data collected on entry",
153
153
  isRouteComplete: true,
154
154
  },
155
155
  ];
156
156
  }
157
- else if (result.state) {
158
- // Found a non-skipped state
157
+ else if (result.step) {
158
+ // Found a non-skipped step
159
159
  candidates.push({
160
- state: result.state,
160
+ step: result.step,
161
161
  condition: result.condition,
162
- requiredData: result.state.requiredData,
163
- gatherFields: result.state.gatherFields,
162
+ requires: result.step.requires,
163
+ collectFields: result.step.collectFields,
164
164
  });
165
165
  }
166
- // If no state found and not complete, fall through to return empty candidates
166
+ // If no step found and not complete, fall through to return empty candidates
167
167
  }
168
168
  else {
169
169
  candidates.push({
170
- state: initialState,
171
- requiredData: initialState.requiredData,
172
- gatherFields: initialState.gatherFields,
170
+ step: initialStep,
171
+ requires: initialStep.requires,
172
+ collectFields: initialStep.collectFields,
173
173
  });
174
174
  }
175
175
  return candidates;
176
176
  }
177
- const transitions = currentState.getTransitions();
177
+ const transitions = currentStep.getTransitions();
178
178
  let hasEndRoute = false;
179
179
  for (const transition of transitions) {
180
180
  const target = transition.getTarget();
181
- // Check for END_STATE transition (no target state)
181
+ // Check for END_ROUTE transition (no target step)
182
182
  if (!target &&
183
- transition.spec.state &&
184
- typeof transition.spec.state === "symbol") {
183
+ transition.spec.step &&
184
+ typeof transition.spec.step === "symbol") {
185
185
  hasEndRoute = true;
186
186
  continue;
187
187
  }
188
188
  if (!target)
189
189
  continue;
190
- if (target.shouldSkip(extracted)) {
191
- logger_1.logger.debug(`[RoutingEngine] Skipping state ${target.id} (skipIf condition met)`);
192
- // Recursively traverse to find next valid state or END_STATE
193
- const result = this.findFirstValidStateRecursive(target, extracted, new Set([currentState.id]) // Already visited current state
190
+ if (target.shouldSkip(data)) {
191
+ logger_1.logger.debug(`[RoutingEngine] Skipping step ${target.id} (skipIf condition met)`);
192
+ // Recursively traverse to find next valid step or END_ROUTE
193
+ const result = this.findFirstValidStepRecursive(target, data, new Set([currentStep.id]) // Already visited current step
194
194
  );
195
195
  if (result.isRouteComplete) {
196
196
  hasEndRoute = true;
197
197
  }
198
- else if (result.state) {
199
- // Found a non-skipped state deeper in the chain
198
+ else if (result.step) {
199
+ // Found a non-skipped step deeper in the chain
200
200
  candidates.push({
201
- state: result.state,
201
+ step: result.step,
202
202
  condition: result.condition || transition.condition,
203
- requiredData: result.state.requiredData,
204
- gatherFields: result.state.gatherFields,
203
+ requires: result.step.requires,
204
+ collectFields: result.step.collectFields,
205
205
  });
206
206
  }
207
207
  continue;
208
208
  }
209
209
  candidates.push({
210
- state: target,
210
+ step: target,
211
211
  condition: transition.condition,
212
- requiredData: target.requiredData,
213
- gatherFields: target.gatherFields,
212
+ requires: target.requires,
213
+ collectFields: target.collectFields,
214
214
  });
215
215
  }
216
216
  // If no valid candidates found
217
217
  if (candidates.length === 0) {
218
- // If current state has END_STATE transition, the route is complete
218
+ // If current step has END_ROUTE transition, the route is complete
219
219
  if (hasEndRoute) {
220
- logger_1.logger.debug(`[RoutingEngine] Route complete: all states processed, END_STATE reached`);
221
- // Return current state with completion flag
220
+ logger_1.logger.debug(`[RoutingEngine] Route complete: all steps processed, END_ROUTE reached`);
221
+ // Return current step with completion flag
222
222
  return [
223
223
  {
224
- state: currentState,
224
+ step: currentStep,
225
225
  condition: "Route complete - all data collected",
226
226
  isRouteComplete: true,
227
227
  },
228
228
  ];
229
229
  }
230
- // Otherwise, stay in current state if it's still valid
231
- if (!currentState.shouldSkip(extracted)) {
230
+ // Otherwise, stay in current step if it's still valid
231
+ if (!currentStep.shouldSkip(data)) {
232
232
  candidates.push({
233
- state: currentState,
234
- condition: "Continue in current state (no valid transitions)",
235
- requiredData: currentState.requiredData,
236
- gatherFields: currentState.gatherFields,
233
+ step: currentStep,
234
+ condition: "Continue in current step (no valid transitions)",
235
+ requires: currentStep.requires,
236
+ collectFields: currentStep.collectFields,
237
237
  });
238
238
  }
239
239
  }
240
240
  return candidates;
241
241
  }
242
242
  /**
243
- * Full routing orchestration: builds prompt and schema, calls AI, selects route/state,
243
+ * Full routing orchestration: builds prompt and schema, calls AI, selects route/step,
244
244
  * and updates the session (including initialData merge when entering a new route).
245
245
  *
246
- * OPTIMIZATION: If there's only 1 route, skips route scoring and only does state selection.
246
+ * OPTIMIZATION: If there's only 1 route, skips route scoring and only does step selection.
247
247
  */
248
- async decideRouteAndState(params) {
248
+ async decideRouteAndStep(params) {
249
249
  const { routes, session, history, agentMeta, ai, context, signal } = params;
250
250
  if (routes.length === 0) {
251
251
  return { session };
252
252
  }
253
- // OPTIMIZATION: Single route - skip route scoring, only do state selection
253
+ // OPTIMIZATION: Single route - skip route scoring, only do step selection
254
254
  if (routes.length === 1) {
255
- return this.decideSingleRouteState({
255
+ return this.decideSingleRouteStep({
256
256
  route: routes[0],
257
257
  session,
258
258
  history,
@@ -263,37 +263,37 @@ class RoutingEngine {
263
263
  });
264
264
  }
265
265
  const lastUserMessage = (0, event_1.getLastMessageFromHistory)(history);
266
- let activeRouteStates;
266
+ let activeRouteSteps;
267
267
  let activeRoute;
268
268
  let isRouteComplete = false;
269
269
  if (session.currentRoute) {
270
270
  activeRoute = routes.find((r) => r.id === session.currentRoute?.id);
271
271
  if (activeRoute) {
272
- const currentState = session.currentState
273
- ? activeRoute.getState(session.currentState.id)
272
+ const currentStep = session.currentStep
273
+ ? activeRoute.getStep(session.currentStep.id)
274
274
  : undefined;
275
- const candidates = this.getCandidateStates(activeRoute, currentState, session.extracted || {});
275
+ const candidates = this.getCandidateSteps(activeRoute, currentStep, session.data || {});
276
276
  // Check if route is complete
277
277
  if (candidates.length === 1 && candidates[0].isRouteComplete) {
278
278
  isRouteComplete = true;
279
279
  logger_1.logger.debug(`[RoutingEngine] Route ${activeRoute.title} is complete - all data collected`);
280
- // Don't include states in routing if route is complete
281
- activeRouteStates = undefined;
280
+ // Don't include steps in routing if route is complete
281
+ activeRouteSteps = undefined;
282
282
  }
283
283
  else {
284
- activeRouteStates = candidates.map((c) => ({
285
- stateId: c.state.id,
286
- description: c.state.description || "",
284
+ activeRouteSteps = candidates.map((c) => ({
285
+ stepId: c.step.id,
286
+ description: c.step.description || "",
287
287
  condition: c.condition,
288
- requiredData: c.requiredData,
289
- gatherFields: c.gatherFields,
288
+ requires: c.requires,
289
+ collectFields: c.collectFields,
290
290
  }));
291
- logger_1.logger.debug(`[RoutingEngine] Found ${activeRouteStates.length} candidate states for active route`);
291
+ logger_1.logger.debug(`[RoutingEngine] Found ${activeRouteSteps.length} candidate steps for active route`);
292
292
  }
293
293
  }
294
294
  }
295
- const routingSchema = this.buildDynamicRoutingSchema(routes, undefined, activeRouteStates);
296
- const routingPrompt = this.buildRoutingPrompt(history, routes, lastUserMessage, agentMeta, session, activeRouteStates);
295
+ const routingSchema = this.buildDynamicRoutingSchema(routes, undefined, activeRouteSteps);
296
+ const routingPrompt = this.buildRoutingPrompt(history, routes, lastUserMessage, agentMeta, session, activeRouteSteps);
297
297
  const routingResult = await ai.generateMessage({
298
298
  prompt: routingPrompt,
299
299
  history,
@@ -305,7 +305,7 @@ class RoutingEngine {
305
305
  },
306
306
  });
307
307
  let selectedRoute;
308
- let selectedState;
308
+ let selectedStep;
309
309
  let responseDirectives;
310
310
  let updatedSession = session;
311
311
  if (routingResult.structured?.routes) {
@@ -317,12 +317,12 @@ class RoutingEngine {
317
317
  selectedRoute = routes.find((r) => r.id === decision.routeId);
318
318
  responseDirectives = routingResult.structured.responseDirectives;
319
319
  if (selectedRoute === activeRoute &&
320
- routingResult.structured.selectedStateId &&
320
+ routingResult.structured.selectedStepId &&
321
321
  activeRoute) {
322
- selectedState = activeRoute.getState(routingResult.structured.selectedStateId);
323
- if (selectedState) {
324
- logger_1.logger.debug(`[RoutingEngine] AI selected state: ${selectedState.id} in active route`);
325
- logger_1.logger.debug(`[RoutingEngine] State reasoning: ${routingResult.structured.stateReasoning}`);
322
+ selectedStep = activeRoute.getStep(routingResult.structured.selectedStepId);
323
+ if (selectedStep) {
324
+ logger_1.logger.debug(`[RoutingEngine] AI selected step: ${selectedStep.id} in active route`);
325
+ logger_1.logger.debug(`[RoutingEngine] Step reasoning: ${routingResult.structured.stepReasoning}`);
326
326
  }
327
327
  }
328
328
  if (selectedRoute) {
@@ -331,7 +331,7 @@ class RoutingEngine {
331
331
  session.currentRoute.id !== selectedRoute.id) {
332
332
  updatedSession = (0, session_1.enterRoute)(session, selectedRoute.id, selectedRoute.title);
333
333
  if (selectedRoute.initialData) {
334
- updatedSession = (0, session_1.mergeExtracted)(updatedSession, selectedRoute.initialData);
334
+ updatedSession = (0, session_1.mergeCollected)(updatedSession, selectedRoute.initialData);
335
335
  logger_1.logger.debug(`[RoutingEngine] Merged initial data:`, selectedRoute.initialData);
336
336
  }
337
337
  logger_1.logger.debug(`[RoutingEngine] Entered route: ${selectedRoute.title}`);
@@ -340,17 +340,17 @@ class RoutingEngine {
340
340
  }
341
341
  return {
342
342
  selectedRoute,
343
- selectedState,
343
+ selectedStep,
344
344
  responseDirectives,
345
345
  session: updatedSession,
346
346
  isRouteComplete,
347
347
  };
348
348
  }
349
349
  /**
350
- * Build prompt for state selection within a single route
350
+ * Build prompt for step selection within a single route
351
351
  * @private
352
352
  */
353
- buildStateSelectionPrompt(route, currentState, candidates, extracted, history, lastMessage, agentMeta) {
353
+ buildStepSelectionPrompt(route, currentStep, candidates, data, history, lastMessage, agentMeta) {
354
354
  const pc = new PromptComposer_1.PromptComposer();
355
355
  // Add agent metadata
356
356
  if (agentMeta?.name || agentMeta?.goal || agentMeta?.description) {
@@ -364,79 +364,79 @@ class RoutingEngine {
364
364
  pc.addPersonality(personality);
365
365
  // Add route context
366
366
  pc.addInstruction(`Active Route: ${route.title}\nDescription: ${route.description || "N/A"}`);
367
- // Add current state context
368
- if (currentState) {
369
- pc.addInstruction(`Current State: ${currentState.id}\nDescription: ${currentState.description || "N/A"}`);
367
+ // Add current step context
368
+ if (currentStep) {
369
+ pc.addInstruction(`Current Step: ${currentStep.id}\nDescription: ${currentStep.description || "N/A"}`);
370
370
  }
371
371
  else {
372
- pc.addInstruction("Current State: None (entering route)");
372
+ pc.addInstruction("Current Step: None (entering route)");
373
373
  }
374
- // Add extracted data context
375
- if (Object.keys(extracted).length > 0) {
376
- pc.addInstruction(`Extracted Data So Far:\n${JSON.stringify(extracted, null, 2)}`);
374
+ // Add collected data context
375
+ if (Object.keys(data).length > 0) {
376
+ pc.addInstruction(`Collected Data So Far:\n${JSON.stringify(data, null, 2)}`);
377
377
  }
378
378
  else {
379
- pc.addInstruction("Extracted Data: None yet");
379
+ pc.addInstruction("Collected Data: None yet");
380
380
  }
381
381
  // Add conversation history
382
382
  pc.addInteractionHistory(history);
383
383
  pc.addLastMessage(lastMessage);
384
- // Add candidate states
385
- const stateDescriptions = candidates.map((candidate, idx) => {
384
+ // Add candidate steps
385
+ const stepDescriptions = candidates.map((candidate, idx) => {
386
386
  const parts = [
387
- `${idx + 1}. State ID: ${candidate.state.id}`,
388
- ` Description: ${candidate.state.description || "N/A"}`,
387
+ `${idx + 1}. Step ID: ${candidate.step.id}`,
388
+ ` Description: ${candidate.step.description || "N/A"}`,
389
389
  ];
390
390
  if (candidate.condition) {
391
391
  parts.push(` Condition: ${candidate.condition}`);
392
392
  }
393
- if (candidate.requiredData && candidate.requiredData.length > 0) {
394
- parts.push(` Required Data: ${candidate.requiredData.join(", ")}`);
393
+ if (candidate.requires && candidate.requires.length > 0) {
394
+ parts.push(` Required Data: ${candidate.requires.join(", ")}`);
395
395
  }
396
- if (candidate.gatherFields && candidate.gatherFields.length > 0) {
397
- parts.push(` Gathers: ${candidate.gatherFields.join(", ")}`);
396
+ if (candidate.collectFields && candidate.collectFields.length > 0) {
397
+ parts.push(` Collects: ${candidate.collectFields.join(", ")}`);
398
398
  }
399
399
  return parts.join("\n");
400
400
  });
401
- pc.addInstruction(`Available States to Transition To:\n${stateDescriptions.join("\n\n")}`);
401
+ pc.addInstruction(`Available Steps to Transition To:\n${stepDescriptions.join("\n\n")}`);
402
402
  // Add decision instructions
403
403
  pc.addInstruction([
404
- "Task: Decide which state to transition to based on:",
404
+ "Task: Decide which step to transition to based on:",
405
405
  "1. The user's current message and intent",
406
406
  "2. The conversation history and context",
407
- "3. The extracted data we already have",
408
- "4. The conditions and requirements of each state",
407
+ "3. The collected data we already have",
408
+ "4. The conditions and requirements of each step",
409
409
  "5. The logical flow of the conversation",
410
410
  "",
411
411
  "Rules:",
412
- "- If a state has a condition, evaluate whether it's met based on context",
413
- "- If a state requires data we don't have, consider if we should gather it now",
414
- "- Choose the state that makes the most sense for moving the conversation forward",
415
- "- States with skipIf conditions that are met have already been filtered out",
412
+ "- If a step has a condition, evaluate whether it's met based on context",
413
+ "- If a step requires data we don't have, consider if we should collect it now",
414
+ "- Choose the step that makes the most sense for moving the conversation forward",
415
+ "- Steps with skipIf conditions that are met have already been filtered out",
416
416
  "",
417
417
  "Return ONLY JSON matching the provided schema.",
418
418
  ].join("\n"));
419
419
  return pc.build();
420
420
  }
421
421
  /**
422
- * Build schema for state selection
422
+ * Build schema for step selection
423
423
  * @private
424
424
  */
425
- buildStateSelectionSchema(validStateIds) {
425
+ buildStepSelectionSchema(validStepIds) {
426
426
  return {
427
- description: "State transition decision based on conversation context and extracted data",
427
+ description: "Step transition decision based on conversation context and collected data",
428
428
  type: "object",
429
429
  properties: {
430
430
  reasoning: {
431
431
  type: "string",
432
432
  nullable: false,
433
- description: "Brief explanation of why this state was selected",
433
+ description: "Brief explanation of why this step was selected",
434
434
  },
435
- selectedStateId: {
435
+ selectedStepId: {
436
436
  type: "string",
437
437
  nullable: false,
438
- description: "The ID of the selected state to transition to",
439
- enum: validStateIds,
438
+ description: "The ID of the selected step to transition to",
439
+ enum: validStepIds,
440
440
  },
441
441
  responseDirectives: {
442
442
  type: "array",
@@ -444,11 +444,11 @@ class RoutingEngine {
444
444
  description: "Optional bullet points the response should address (concise)",
445
445
  },
446
446
  },
447
- required: ["reasoning", "selectedStateId"],
447
+ required: ["reasoning", "selectedStepId"],
448
448
  additionalProperties: false,
449
449
  };
450
450
  }
451
- buildDynamicRoutingSchema(routes, extrasSchema, activeRouteStates) {
451
+ buildDynamicRoutingSchema(routes, extrasSchema, activeRouteSteps) {
452
452
  const routeIds = routes.map((r) => r.id);
453
453
  const routeProperties = {};
454
454
  for (const id of routeIds) {
@@ -485,24 +485,24 @@ class RoutingEngine {
485
485
  required: ["context", "routes"],
486
486
  additionalProperties: false,
487
487
  };
488
- // Add state selection fields if there's an active route with states
489
- if (activeRouteStates && activeRouteStates.length > 0) {
488
+ // Add step selection fields if there's an active route with steps
489
+ if (activeRouteSteps && activeRouteSteps.length > 0) {
490
490
  base.properties = base.properties || {};
491
- base.properties.selectedStateId = {
491
+ base.properties.selectedStepId = {
492
492
  type: "string",
493
493
  nullable: false,
494
- description: "The state ID to transition to within the active route (required if continuing in current route)",
495
- enum: activeRouteStates.map((s) => s.stateId),
494
+ description: "The step ID to transition to within the active route (required if continuing in current route)",
495
+ enum: activeRouteSteps.map((s) => s.stepId),
496
496
  };
497
- base.properties.stateReasoning = {
497
+ base.properties.stepReasoning = {
498
498
  type: "string",
499
499
  nullable: false,
500
- description: "Brief explanation of why this state was selected",
500
+ description: "Brief explanation of why this step was selected",
501
501
  };
502
502
  base.required = [
503
503
  ...(base.required || []),
504
- "selectedStateId",
505
- "stateReasoning",
504
+ "selectedStepId",
505
+ "stepReasoning",
506
506
  ];
507
507
  }
508
508
  if (extrasSchema) {
@@ -511,7 +511,7 @@ class RoutingEngine {
511
511
  }
512
512
  return base;
513
513
  }
514
- buildRoutingPrompt(history, routes, lastMessage, agentMeta, session, activeRouteStates) {
514
+ buildRoutingPrompt(history, routes, lastMessage, agentMeta, session, activeRouteSteps) {
515
515
  const pc = new PromptComposer_1.PromptComposer();
516
516
  if (agentMeta?.name || agentMeta?.goal || agentMeta?.description) {
517
517
  pc.addAgentMeta({
@@ -529,45 +529,45 @@ class RoutingEngine {
529
529
  "Current conversation context:",
530
530
  `- Active route: ${session.currentRoute.title} (${session.currentRoute.id})`,
531
531
  ];
532
- if (session.currentState) {
533
- sessionInfo.push(`- Current state: ${session.currentState.id}`);
534
- if (session.currentState.description) {
535
- sessionInfo.push(` "${session.currentState.description}"`);
532
+ if (session.currentStep) {
533
+ sessionInfo.push(`- Current step: ${session.currentStep.id}`);
534
+ if (session.currentStep.description) {
535
+ sessionInfo.push(` "${session.currentStep.description}"`);
536
536
  }
537
537
  }
538
- if (session.extracted && Object.keys(session.extracted).length > 0) {
539
- sessionInfo.push(`- Extracted data: ${JSON.stringify(session.extracted)}`);
538
+ if (session.data && Object.keys(session.data).length > 0) {
539
+ sessionInfo.push(`- Collected data: ${JSON.stringify(session.data)}`);
540
540
  }
541
541
  sessionInfo.push("Note: User is mid-conversation. They may want to continue current route or switch to a new one based on their intent.");
542
542
  pc.addInstruction(sessionInfo.join("\n"));
543
- // Add available states for the active route
544
- if (activeRouteStates && activeRouteStates.length > 0) {
545
- const stateInfo = [
543
+ // Add available steps for the active route
544
+ if (activeRouteSteps && activeRouteSteps.length > 0) {
545
+ const stepInfo = [
546
546
  "",
547
- "Available states in active route (choose one to transition to):",
547
+ "Available steps in active route (choose one to transition to):",
548
548
  ];
549
- activeRouteStates.forEach((state, idx) => {
550
- stateInfo.push(`${idx + 1}. State: ${state.stateId}`);
551
- if (state.description) {
552
- stateInfo.push(` Description: ${state.description}`);
549
+ activeRouteSteps.forEach((step, idx) => {
550
+ stepInfo.push(`${idx + 1}. Step: ${step.stepId}`);
551
+ if (step.description) {
552
+ stepInfo.push(` Description: ${step.description}`);
553
553
  }
554
- if (state.condition) {
555
- stateInfo.push(` Condition: ${state.condition}`);
554
+ if (step.condition) {
555
+ stepInfo.push(` Condition: ${step.condition}`);
556
556
  }
557
- if (state.requiredData && state.requiredData.length > 0) {
558
- stateInfo.push(` Required data: ${state.requiredData.join(", ")}`);
557
+ if (step.requires && step.requires.length > 0) {
558
+ stepInfo.push(` Required data: ${step.requires.join(", ")}`);
559
559
  }
560
- if (state.gatherFields && state.gatherFields.length > 0) {
561
- stateInfo.push(` Will gather: ${state.gatherFields.join(", ")}`);
560
+ if (step.collectFields && step.collectFields.length > 0) {
561
+ stepInfo.push(` Will collect: ${step.collectFields.join(", ")}`);
562
562
  }
563
563
  });
564
- stateInfo.push("");
565
- stateInfo.push("IMPORTANT: You MUST select a state to transition to. Evaluate which state makes the most sense based on:");
566
- stateInfo.push("- The conversation flow and what's been collected");
567
- stateInfo.push("- What data is still needed vs already present");
568
- stateInfo.push("- The logical next step in the conversation");
569
- stateInfo.push("- Whether conditions for states are met");
570
- pc.addInstruction(stateInfo.join("\n"));
564
+ stepInfo.push("");
565
+ stepInfo.push("IMPORTANT: You MUST select a step to transition to. Evaluate which step makes the most sense based on:");
566
+ stepInfo.push("- The conversation flow and what's been collected");
567
+ stepInfo.push("- What data is still needed vs already present");
568
+ stepInfo.push("- The logical next step in the conversation");
569
+ stepInfo.push("- Whether conditions for steps are met");
570
+ pc.addInstruction(stepInfo.join("\n"));
571
571
  }
572
572
  }
573
573
  pc.addInteractionHistory(history);