@falai/agent 0.9.0-alpha-1 → 0.9.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 (217) hide show
  1. package/README.md +34 -22
  2. package/dist/cjs/src/core/Agent.d.ts +77 -59
  3. package/dist/cjs/src/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/src/core/Agent.js +284 -1060
  5. package/dist/cjs/src/core/Agent.js.map +1 -1
  6. package/dist/cjs/src/core/PersistenceManager.d.ts.map +1 -1
  7. package/dist/cjs/src/core/PersistenceManager.js +48 -25
  8. package/dist/cjs/src/core/PersistenceManager.js.map +1 -1
  9. package/dist/cjs/src/core/PromptComposer.d.ts +1 -1
  10. package/dist/cjs/src/core/PromptComposer.d.ts.map +1 -1
  11. package/dist/cjs/src/core/PromptComposer.js.map +1 -1
  12. package/dist/cjs/src/core/ResponseEngine.d.ts +13 -12
  13. package/dist/cjs/src/core/ResponseEngine.d.ts.map +1 -1
  14. package/dist/cjs/src/core/ResponseEngine.js +4 -4
  15. package/dist/cjs/src/core/ResponseEngine.js.map +1 -1
  16. package/dist/cjs/src/core/ResponseModal.d.ts +205 -0
  17. package/dist/cjs/src/core/ResponseModal.d.ts.map +1 -0
  18. package/dist/cjs/src/core/ResponseModal.js +1328 -0
  19. package/dist/cjs/src/core/ResponseModal.js.map +1 -0
  20. package/dist/cjs/src/core/ResponsePipeline.d.ts +66 -38
  21. package/dist/cjs/src/core/ResponsePipeline.d.ts.map +1 -1
  22. package/dist/cjs/src/core/ResponsePipeline.js +72 -4
  23. package/dist/cjs/src/core/ResponsePipeline.js.map +1 -1
  24. package/dist/cjs/src/core/Route.d.ts +24 -5
  25. package/dist/cjs/src/core/Route.d.ts.map +1 -1
  26. package/dist/cjs/src/core/Route.js +45 -1
  27. package/dist/cjs/src/core/Route.js.map +1 -1
  28. package/dist/cjs/src/core/RoutingEngine.d.ts +31 -6
  29. package/dist/cjs/src/core/RoutingEngine.d.ts.map +1 -1
  30. package/dist/cjs/src/core/RoutingEngine.js +113 -9
  31. package/dist/cjs/src/core/RoutingEngine.js.map +1 -1
  32. package/dist/cjs/src/core/SessionManager.d.ts +14 -4
  33. package/dist/cjs/src/core/SessionManager.d.ts.map +1 -1
  34. package/dist/cjs/src/core/SessionManager.js +25 -5
  35. package/dist/cjs/src/core/SessionManager.js.map +1 -1
  36. package/dist/cjs/src/core/Step.d.ts +10 -10
  37. package/dist/cjs/src/core/Step.d.ts.map +1 -1
  38. package/dist/cjs/src/core/Step.js.map +1 -1
  39. package/dist/cjs/src/core/ToolExecutor.d.ts +4 -2
  40. package/dist/cjs/src/core/ToolExecutor.d.ts.map +1 -1
  41. package/dist/cjs/src/core/ToolExecutor.js +13 -3
  42. package/dist/cjs/src/core/ToolExecutor.js.map +1 -1
  43. package/dist/cjs/src/index.d.ts +3 -1
  44. package/dist/cjs/src/index.d.ts.map +1 -1
  45. package/dist/cjs/src/index.js +7 -1
  46. package/dist/cjs/src/index.js.map +1 -1
  47. package/dist/cjs/src/types/agent.d.ts +42 -21
  48. package/dist/cjs/src/types/agent.d.ts.map +1 -1
  49. package/dist/cjs/src/types/agent.js.map +1 -1
  50. package/dist/cjs/src/types/ai.d.ts +1 -1
  51. package/dist/cjs/src/types/ai.d.ts.map +1 -1
  52. package/dist/cjs/src/types/index.d.ts +1 -1
  53. package/dist/cjs/src/types/index.d.ts.map +1 -1
  54. package/dist/cjs/src/types/index.js.map +1 -1
  55. package/dist/cjs/src/types/persistence.d.ts +0 -1
  56. package/dist/cjs/src/types/persistence.d.ts.map +1 -1
  57. package/dist/cjs/src/types/route.d.ts +22 -16
  58. package/dist/cjs/src/types/route.d.ts.map +1 -1
  59. package/dist/cjs/src/types/session.d.ts +6 -11
  60. package/dist/cjs/src/types/session.d.ts.map +1 -1
  61. package/dist/cjs/src/types/tool.d.ts +12 -6
  62. package/dist/cjs/src/types/tool.d.ts.map +1 -1
  63. package/dist/cjs/src/utils/clone.d.ts.map +1 -1
  64. package/dist/cjs/src/utils/clone.js +0 -4
  65. package/dist/cjs/src/utils/clone.js.map +1 -1
  66. package/dist/cjs/src/utils/history.d.ts +30 -1
  67. package/dist/cjs/src/utils/history.d.ts.map +1 -1
  68. package/dist/cjs/src/utils/history.js +169 -23
  69. package/dist/cjs/src/utils/history.js.map +1 -1
  70. package/dist/cjs/src/utils/index.d.ts +1 -1
  71. package/dist/cjs/src/utils/index.d.ts.map +1 -1
  72. package/dist/cjs/src/utils/index.js +5 -1
  73. package/dist/cjs/src/utils/index.js.map +1 -1
  74. package/dist/cjs/src/utils/session.d.ts +2 -2
  75. package/dist/cjs/src/utils/session.d.ts.map +1 -1
  76. package/dist/cjs/src/utils/session.js +6 -26
  77. package/dist/cjs/src/utils/session.js.map +1 -1
  78. package/dist/src/core/Agent.d.ts +77 -59
  79. package/dist/src/core/Agent.d.ts.map +1 -1
  80. package/dist/src/core/Agent.js +285 -1061
  81. package/dist/src/core/Agent.js.map +1 -1
  82. package/dist/src/core/PersistenceManager.d.ts.map +1 -1
  83. package/dist/src/core/PersistenceManager.js +48 -25
  84. package/dist/src/core/PersistenceManager.js.map +1 -1
  85. package/dist/src/core/PromptComposer.d.ts +1 -1
  86. package/dist/src/core/PromptComposer.d.ts.map +1 -1
  87. package/dist/src/core/PromptComposer.js.map +1 -1
  88. package/dist/src/core/ResponseEngine.d.ts +13 -12
  89. package/dist/src/core/ResponseEngine.d.ts.map +1 -1
  90. package/dist/src/core/ResponseEngine.js +4 -4
  91. package/dist/src/core/ResponseEngine.js.map +1 -1
  92. package/dist/src/core/ResponseModal.d.ts +205 -0
  93. package/dist/src/core/ResponseModal.d.ts.map +1 -0
  94. package/dist/src/core/ResponseModal.js +1323 -0
  95. package/dist/src/core/ResponseModal.js.map +1 -0
  96. package/dist/src/core/ResponsePipeline.d.ts +66 -38
  97. package/dist/src/core/ResponsePipeline.d.ts.map +1 -1
  98. package/dist/src/core/ResponsePipeline.js +72 -4
  99. package/dist/src/core/ResponsePipeline.js.map +1 -1
  100. package/dist/src/core/Route.d.ts +24 -5
  101. package/dist/src/core/Route.d.ts.map +1 -1
  102. package/dist/src/core/Route.js +45 -1
  103. package/dist/src/core/Route.js.map +1 -1
  104. package/dist/src/core/RoutingEngine.d.ts +31 -6
  105. package/dist/src/core/RoutingEngine.d.ts.map +1 -1
  106. package/dist/src/core/RoutingEngine.js +113 -9
  107. package/dist/src/core/RoutingEngine.js.map +1 -1
  108. package/dist/src/core/SessionManager.d.ts +14 -4
  109. package/dist/src/core/SessionManager.d.ts.map +1 -1
  110. package/dist/src/core/SessionManager.js +25 -5
  111. package/dist/src/core/SessionManager.js.map +1 -1
  112. package/dist/src/core/Step.d.ts +10 -10
  113. package/dist/src/core/Step.d.ts.map +1 -1
  114. package/dist/src/core/Step.js.map +1 -1
  115. package/dist/src/core/ToolExecutor.d.ts +4 -2
  116. package/dist/src/core/ToolExecutor.d.ts.map +1 -1
  117. package/dist/src/core/ToolExecutor.js +13 -3
  118. package/dist/src/core/ToolExecutor.js.map +1 -1
  119. package/dist/src/index.d.ts +3 -1
  120. package/dist/src/index.d.ts.map +1 -1
  121. package/dist/src/index.js +2 -1
  122. package/dist/src/index.js.map +1 -1
  123. package/dist/src/types/agent.d.ts +42 -21
  124. package/dist/src/types/agent.d.ts.map +1 -1
  125. package/dist/src/types/agent.js.map +1 -1
  126. package/dist/src/types/ai.d.ts +1 -1
  127. package/dist/src/types/ai.d.ts.map +1 -1
  128. package/dist/src/types/index.d.ts +1 -1
  129. package/dist/src/types/index.d.ts.map +1 -1
  130. package/dist/src/types/index.js.map +1 -1
  131. package/dist/src/types/persistence.d.ts +0 -1
  132. package/dist/src/types/persistence.d.ts.map +1 -1
  133. package/dist/src/types/route.d.ts +22 -16
  134. package/dist/src/types/route.d.ts.map +1 -1
  135. package/dist/src/types/session.d.ts +6 -11
  136. package/dist/src/types/session.d.ts.map +1 -1
  137. package/dist/src/types/tool.d.ts +12 -6
  138. package/dist/src/types/tool.d.ts.map +1 -1
  139. package/dist/src/utils/clone.d.ts.map +1 -1
  140. package/dist/src/utils/clone.js +0 -4
  141. package/dist/src/utils/clone.js.map +1 -1
  142. package/dist/src/utils/history.d.ts +30 -1
  143. package/dist/src/utils/history.d.ts.map +1 -1
  144. package/dist/src/utils/history.js +165 -23
  145. package/dist/src/utils/history.js.map +1 -1
  146. package/dist/src/utils/index.d.ts +1 -1
  147. package/dist/src/utils/index.d.ts.map +1 -1
  148. package/dist/src/utils/index.js +1 -1
  149. package/dist/src/utils/index.js.map +1 -1
  150. package/dist/src/utils/session.d.ts +2 -2
  151. package/dist/src/utils/session.d.ts.map +1 -1
  152. package/dist/src/utils/session.js +6 -26
  153. package/dist/src/utils/session.js.map +1 -1
  154. package/docs/README.md +5 -4
  155. package/docs/api/README.md +195 -4
  156. package/docs/api/overview.md +232 -13
  157. package/docs/core/agent/README.md +162 -17
  158. package/docs/core/agent/context-management.md +39 -15
  159. package/docs/core/agent/session-management.md +49 -16
  160. package/docs/core/ai-integration/prompt-composition.md +38 -14
  161. package/docs/core/ai-integration/response-processing.md +28 -17
  162. package/docs/core/conversation-flows/data-collection.md +103 -25
  163. package/docs/core/conversation-flows/route-dsl.md +45 -22
  164. package/docs/core/conversation-flows/routes.md +74 -18
  165. package/docs/core/conversation-flows/step-transitions.md +3 -3
  166. package/docs/core/conversation-flows/steps.md +39 -15
  167. package/docs/core/routing/intelligent-routing.md +18 -9
  168. package/docs/core/tools/tool-definition.md +8 -8
  169. package/docs/core/tools/tool-execution.md +26 -26
  170. package/docs/core/tools/tool-scoping.md +5 -5
  171. package/docs/guides/getting-started/README.md +54 -32
  172. package/docs/guides/migration/README.md +72 -0
  173. package/docs/guides/migration/response-modal-refactor.md +518 -0
  174. package/examples/advanced-patterns/knowledge-based-agent.ts +37 -28
  175. package/examples/advanced-patterns/persistent-onboarding.ts +70 -41
  176. package/examples/advanced-patterns/route-lifecycle-hooks.ts +28 -2
  177. package/examples/advanced-patterns/streaming-responses.ts +197 -119
  178. package/examples/ai-providers/anthropic-integration.ts +40 -33
  179. package/examples/ai-providers/openai-integration.ts +25 -25
  180. package/examples/conversation-flows/completion-transitions.ts +36 -32
  181. package/examples/core-concepts/basic-agent.ts +76 -78
  182. package/examples/core-concepts/modern-streaming-api.ts +309 -0
  183. package/examples/core-concepts/schema-driven-extraction.ts +20 -16
  184. package/examples/core-concepts/session-management.ts +65 -53
  185. package/examples/integrations/database-integration.ts +49 -34
  186. package/examples/integrations/healthcare-integration.ts +96 -91
  187. package/examples/integrations/search-integration.ts +79 -82
  188. package/examples/integrations/server-session-management.ts +25 -17
  189. package/examples/persistence/database-persistence.ts +61 -45
  190. package/examples/persistence/memory-sessions.ts +52 -63
  191. package/examples/persistence/redis-persistence.ts +81 -95
  192. package/examples/tools/basic-tools.ts +73 -62
  193. package/examples/tools/data-enrichment-tools.ts +52 -44
  194. package/package.json +1 -1
  195. package/src/core/Agent.ts +396 -1499
  196. package/src/core/PersistenceManager.ts +51 -27
  197. package/src/core/PromptComposer.ts +1 -1
  198. package/src/core/ResponseEngine.ts +21 -19
  199. package/src/core/ResponseModal.ts +1722 -0
  200. package/src/core/ResponsePipeline.ts +175 -60
  201. package/src/core/Route.ts +58 -6
  202. package/src/core/RoutingEngine.ts +174 -27
  203. package/src/core/SessionManager.ts +32 -8
  204. package/src/core/Step.ts +20 -12
  205. package/src/core/ToolExecutor.ts +19 -5
  206. package/src/index.ts +11 -0
  207. package/src/types/agent.ts +47 -23
  208. package/src/types/ai.ts +1 -1
  209. package/src/types/index.ts +2 -0
  210. package/src/types/persistence.ts +0 -1
  211. package/src/types/route.ts +22 -16
  212. package/src/types/session.ts +6 -12
  213. package/src/types/tool.ts +15 -9
  214. package/src/utils/clone.ts +6 -8
  215. package/src/utils/history.ts +190 -27
  216. package/src/utils/index.ts +4 -0
  217. package/src/utils/session.ts +6 -31
@@ -1,20 +1,22 @@
1
- # Schema-Driven Data Collection
1
+ # Agent-Level Schema-Driven Data Collection
2
2
 
3
- @falai/agent implements a powerful schema-first approach to data collection, enabling type-safe, structured information extraction from natural conversations. Unlike traditional form-filling, this system uses AI to naturally gather information while maintaining data integrity.
3
+ @falai/agent implements a powerful agent-level schema-first approach to data collection, enabling type-safe, structured information extraction from natural conversations across all routes. Unlike traditional route-specific data collection, this system centralizes data schemas at the agent level while allowing routes to specify completion requirements.
4
4
 
5
5
  ## Overview
6
6
 
7
- The data collection system provides:
7
+ The agent-level data collection system provides:
8
8
 
9
- - **JSON Schema Contracts**: Define data structures upfront with validation
9
+ - **Centralized JSON Schema**: Define comprehensive data structures at the agent level
10
+ - **Cross-Route Data Sharing**: Data collected by any route is available to all routes
11
+ - **Route Completion Logic**: Routes complete when their required fields are satisfied
10
12
  - **Type-Safe Extraction**: Automatic mapping from AI responses to typed data
11
13
  - **Natural Conversations**: AI handles information gathering conversationally
12
- - **Validation & Enrichment**: Lifecycle hooks for data processing
13
- - **Session Persistence**: Data survives across conversation turns
14
+ - **Validation & Enrichment**: Agent-level lifecycle hooks for data processing
15
+ - **Session Persistence**: Data survives across conversation turns and route transitions
14
16
 
15
- ## Schema Definition
17
+ ## Agent-Level Schema Definition
16
18
 
17
- ### Basic Schema
19
+ ### Centralized Schema
18
20
 
19
21
  ```typescript
20
22
  interface UserProfile {
@@ -26,10 +28,19 @@ interface UserProfile {
26
28
  notifications: boolean;
27
29
  theme: "light" | "dark";
28
30
  };
31
+ // Additional fields for other routes
32
+ supportTicketId?: string;
33
+ issueType?: string;
34
+ feedbackRating?: number;
35
+ subscriptionTier?: "free" | "premium" | "enterprise";
29
36
  }
30
37
 
31
- const userProfileRoute = agent.createRoute<UserProfile>({
32
- title: "User Profile Collection",
38
+ // Define schema at agent level
39
+ const agent = new Agent<{}, UserProfile>({
40
+ name: "User Management Agent",
41
+ provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
42
+
43
+ // Comprehensive agent-level schema
33
44
  schema: {
34
45
  type: "object",
35
46
  properties: {
@@ -63,9 +74,32 @@ const userProfileRoute = agent.createRoute<UserProfile>({
63
74
  },
64
75
  },
65
76
  },
77
+ supportTicketId: { type: "string" },
78
+ issueType: { type: "string" },
79
+ feedbackRating: { type: "number", minimum: 1, maximum: 5 },
80
+ subscriptionTier: { type: "string", enum: ["free", "premium", "enterprise"] }
66
81
  },
67
82
  required: ["name", "email"],
68
- },
83
+ }
84
+ });
85
+
86
+ // Routes specify required fields instead of schemas
87
+ const profileRoute = agent.createRoute({
88
+ title: "User Profile Collection",
89
+ requiredFields: ["name", "email", "age"],
90
+ optionalFields: ["interests", "preferences"]
91
+ });
92
+
93
+ const supportRoute = agent.createRoute({
94
+ title: "Support Ticket",
95
+ requiredFields: ["name", "email", "issueType"],
96
+ optionalFields: ["supportTicketId"]
97
+ });
98
+
99
+ const feedbackRoute = agent.createRoute({
100
+ title: "Feedback Collection",
101
+ requiredFields: ["name", "email", "feedbackRating"],
102
+ optionalFields: ["subscriptionTier"]
69
103
  });
70
104
  ```
71
105
 
@@ -128,24 +162,33 @@ const complexSchema = {
128
162
 
129
163
  ## Step-Level Data Collection
130
164
 
131
- ### Basic Collection
165
+ ### Basic Collection with Agent-Level Data
132
166
 
133
167
  ```typescript
134
168
  const profileRoute = agent
135
169
  .createRoute({
136
170
  title: "Profile Collection",
137
- schema: userProfileSchema,
171
+ requiredFields: ["name", "email", "age"], // Required for route completion
172
+ optionalFields: ["interests"], // Optional but helpful
138
173
  initialStep: {
139
174
  prompt:
140
175
  "Hi! I'm collecting some information to personalize your experience. What's your name?",
141
- collect: ["name"], // Maps to schema field
176
+ collect: ["name"], // Maps to agent schema field
142
177
  },
143
178
  })
144
179
  .nextStep({
145
180
  prompt: "Thanks {{name}}! What's your email address?",
146
181
  collect: ["email"],
147
182
  requires: ["name"], // Must have name before collecting email
183
+ })
184
+ .nextStep({
185
+ prompt: "What's your age?",
186
+ collect: ["age"],
187
+ requires: ["name", "email"],
148
188
  });
189
+
190
+ // Route completes when all required fields are collected
191
+ // Data is available to all other routes
149
192
  ```
150
193
 
151
194
  ### Multi-Field Collection
@@ -160,12 +203,12 @@ const comprehensiveStep = {
160
203
  - Your preferred theme (light/dark)
161
204
  `,
162
205
  collect: [
163
- "age", // Single field
164
- "interests", // Array field
206
+ "age", // Single field from agent schema
207
+ "interests", // Array field from agent schema
165
208
  "preferences.notifications", // Nested field (dot notation)
166
209
  "preferences.theme", // Another nested field
167
210
  ],
168
- requires: ["name", "email"],
211
+ requires: ["name", "email"], // Prerequisites from agent data
169
212
  };
170
213
  ```
171
214
 
@@ -175,34 +218,69 @@ const comprehensiveStep = {
175
218
  const conditionalCollection = {
176
219
  prompt: "Would you like to set up notifications? (yes/no)",
177
220
  collect: ["preferences.notifications"],
178
- skipIf: (data) => data.preferences?.notifications !== undefined,
179
- requires: ["name", "email"],
221
+ skipIf: (data) => data.preferences?.notifications !== undefined, // Skip if already collected
222
+ requires: ["name", "email"], // Prerequisites from agent data
180
223
  };
181
224
  ```
182
225
 
226
+ ### Cross-Route Data Sharing
227
+
228
+ With agent-level data collection, routes can share data seamlessly:
229
+
230
+ ```typescript
231
+ // User starts with profile collection
232
+ const response1 = await agent.respond("Hi, I'm John Doe, email john@example.com");
233
+ // Agent data: { name: "John Doe", email: "john@example.com" }
234
+
235
+ // User switches to support - data is already available
236
+ const response2 = await agent.respond("Actually, I need help with a technical issue");
237
+ // Support route can access name and email, only needs to collect issue details
238
+ // Support route: 2/3 required fields already satisfied
239
+
240
+ // User provides issue details
241
+ const response3 = await agent.respond("My account won't sync properly");
242
+ // Support route completes: { name: "John Doe", email: "john@example.com", issueType: "technical" }
243
+
244
+ // Later, user wants to give feedback
245
+ const response4 = await agent.respond("I want to rate my support experience - 5 stars");
246
+ // Feedback route completes immediately: already has name, email, and now rating
247
+ ```
248
+
183
249
  ## Data Validation & Processing
184
250
 
185
- ### Lifecycle Hooks
251
+ ### Agent-Level Lifecycle Hooks
186
252
 
187
253
  ```typescript
188
- const validatedRoute = agent.createRoute({
189
- title: "Validated Collection",
254
+ const agent = new Agent<{}, UserProfile>({
255
+ name: "User Management Agent",
256
+ schema: { /* agent schema */ },
190
257
 
191
- // Agent-level data validation
258
+ // Agent-level data validation (applies to all routes)
192
259
  hooks: {
193
260
  onDataUpdate: (newData, previousData) => {
194
- // Cross-field validation
261
+ // Cross-field validation using complete agent data
195
262
  if (newData.email && newData.confirmEmail) {
196
263
  if (newData.email !== newData.confirmEmail) {
197
264
  throw new Error("Email addresses don't match");
198
265
  }
199
266
  }
200
267
 
201
- // Data enrichment
268
+ // Data enrichment based on agent-level data
202
269
  if (newData.name && !newData.displayName) {
203
270
  newData.displayName = newData.name.split(" ")[0]; // First name only
204
271
  }
205
272
 
273
+ // Auto-set subscription tier based on email domain
274
+ if (newData.email && !newData.subscriptionTier) {
275
+ newData.subscriptionTier = newData.email.includes('@enterprise.com') ? 'enterprise' : 'free';
276
+ }
277
+
278
+ // Validate against agent schema
279
+ const validation = agent.validateData(newData);
280
+ if (!validation.valid) {
281
+ throw new Error(`Data validation failed: ${validation.errors.map(e => e.message).join(', ')}`);
282
+ }
283
+
206
284
  return newData;
207
285
  },
208
286
  },
@@ -31,31 +31,44 @@ const greetingRoute = agent
31
31
  });
32
32
  ```
33
33
 
34
- ### Route with Schema
34
+ ### Route with Agent-Level Schema
35
35
 
36
36
  ```typescript
37
37
  interface UserInfo {
38
38
  name: string;
39
39
  email: string;
40
40
  interests: string[];
41
+ preferences?: object;
42
+ profileComplete?: boolean;
41
43
  }
42
44
 
45
+ // Agent defines comprehensive schema
46
+ const agent = new Agent<{}, UserInfo>({
47
+ name: "Profile Assistant",
48
+ provider: openaiProvider,
49
+ schema: {
50
+ type: "object",
51
+ properties: {
52
+ name: { type: "string" },
53
+ email: { type: "string", format: "email" },
54
+ interests: {
55
+ type: "array",
56
+ items: { type: "string" },
57
+ },
58
+ preferences: { type: "object" },
59
+ profileComplete: { type: "boolean" }
60
+ },
61
+ required: ["name", "email"],
62
+ }
63
+ });
64
+
65
+ // Route specifies required fields instead of schema
43
66
  const userProfileRoute = agent
44
- .createRoute<UserInfo>({
67
+ .createRoute({
45
68
  title: "User Profile Collection",
46
69
  description: "Collect basic user information",
47
- schema: {
48
- type: "object",
49
- properties: {
50
- name: { type: "string" },
51
- email: { type: "string", format: "email" },
52
- interests: {
53
- type: "array",
54
- items: { type: "string" },
55
- },
56
- },
57
- required: ["name", "email"],
58
- },
70
+ requiredFields: ["name", "email", "interests"], // Required for completion
71
+ optionalFields: ["preferences"], // Nice to have
59
72
  initialStep: {
60
73
  prompt: "Let's create your profile. What's your name?",
61
74
  collect: ["name"],
@@ -64,12 +77,12 @@ const userProfileRoute = agent
64
77
  .nextStep({
65
78
  prompt: "Great, {{name}}! What's your email address?",
66
79
  collect: ["email"],
67
- requires: ["name"],
80
+ requires: ["name"], // Prerequisites from agent data
68
81
  })
69
82
  .nextStep({
70
83
  prompt: "What are your interests? (comma-separated)",
71
84
  collect: ["interests"],
72
- requires: ["name", "email"],
85
+ requires: ["name", "email"], // Prerequisites from agent data
73
86
  });
74
87
  ```
75
88
 
@@ -99,9 +112,9 @@ interface StepOptions<TContext, TData> {
99
112
  ```typescript
100
113
  const dataCollectionStep = {
101
114
  prompt: "What's your preferred contact method?",
102
- collect: ["contactMethod"], // Maps to schema field
103
- requires: ["name", "email"], // Must have these fields first
104
- skipIf: (data) => data.contactMethod !== undefined, // Skip if already collected
115
+ collect: ["contactMethod"], // Maps to agent schema field
116
+ requires: ["name", "email"], // Must have these fields from agent data
117
+ skipIf: (data) => data.contactMethod !== undefined, // Skip if already collected by any route
105
118
  };
106
119
  ```
107
120
 
@@ -296,6 +309,10 @@ const advancedRoute = agent.createRoute({
296
309
  title: "Advanced Interaction",
297
310
  description: "Complex multi-step conversation",
298
311
 
312
+ // Route completion requirements
313
+ requiredFields: ["customerName", "email", "issueType"],
314
+ optionalFields: ["phone", "priority"],
315
+
299
316
  // Route-level identity overrides agent identity
300
317
  identity: "You are an expert consultant specializing in {{domain}}",
301
318
 
@@ -316,19 +333,25 @@ const advancedRoute = agent.createRoute({
316
333
  },
317
334
  ],
318
335
 
319
- // Initial data to pre-populate
336
+ // Initial data to pre-populate (maps to agent schema)
320
337
  initialData: {
321
338
  sessionId: generateId(),
322
339
  startTime: new Date().toISOString(),
323
340
  },
324
341
 
325
- // Lifecycle hooks
342
+ // Route-level lifecycle hooks (work with agent data)
326
343
  hooks: {
327
344
  onDataUpdate: (newData, previousData) => {
328
- // Validate or enrich collected data
345
+ // Validate or enrich agent-level collected data
329
346
  if (newData.email && !isValidEmail(newData.email)) {
330
347
  throw new Error("Invalid email format");
331
348
  }
349
+
350
+ // Auto-set priority based on issue type
351
+ if (newData.issueType === 'billing' && !newData.priority) {
352
+ newData.priority = 'high';
353
+ }
354
+
332
355
  return newData;
333
356
  },
334
357
  onContextUpdate: (newContext, previousContext) => {
@@ -1,18 +1,29 @@
1
1
  # Routes
2
2
 
3
- Routes define conversational journeys in @falai/agent. This document covers route definition, lifecycle management, and completion handling.
3
+ Routes define conversational journeys in @falai/agent with agent-level data collection. This document covers route definition with required fields, lifecycle management, and completion handling based on data availability.
4
4
 
5
5
  ## Overview
6
6
 
7
- Routes represent complete conversational workflows that guide users through specific tasks or processes. Each route consists of steps, data collection schemas, and lifecycle hooks.
7
+ Routes represent complete conversational workflows that guide users through specific tasks or processes. Each route specifies required fields for completion, consists of steps that collect data into the agent-level schema, and can complete when their data requirements are satisfied regardless of which route collected the data.
8
8
 
9
- ## Route Definition
9
+ ## Route Definition with Required Fields
10
10
 
11
11
  ```typescript
12
- const bookingRoute = agent.createRoute<BookingData>({
13
- title: "Hotel Booking",
14
- description: "Help users book hotel accommodations",
15
- conditions: ["User wants to book a hotel"],
12
+ // Agent defines comprehensive schema
13
+ interface HotelData {
14
+ destination: string;
15
+ checkIn: string;
16
+ checkOut: string;
17
+ guests: number;
18
+ roomType?: string;
19
+ customerName?: string;
20
+ email?: string;
21
+ phone?: string;
22
+ specialRequests?: string;
23
+ }
24
+
25
+ const agent = new Agent<{}, HotelData>({
26
+ name: "Hotel Booking Agent",
16
27
  schema: {
17
28
  type: "object",
18
29
  properties: {
@@ -20,42 +31,87 @@ const bookingRoute = agent.createRoute<BookingData>({
20
31
  checkIn: { type: "string", format: "date" },
21
32
  checkOut: { type: "string", format: "date" },
22
33
  guests: { type: "number", minimum: 1 },
23
- },
24
- required: ["destination", "checkIn", "checkOut"],
25
- },
34
+ roomType: { type: "string" },
35
+ customerName: { type: "string" },
36
+ email: { type: "string", format: "email" },
37
+ phone: { type: "string" },
38
+ specialRequests: { type: "string" }
39
+ }
40
+ }
41
+ });
42
+
43
+ // Routes specify required fields instead of schemas
44
+ const bookingRoute = agent.createRoute({
45
+ title: "Hotel Booking",
46
+ description: "Help users book hotel accommodations",
47
+ conditions: ["User wants to book a hotel"],
48
+ requiredFields: ["destination", "checkIn", "checkOut", "guests", "customerName", "email"],
49
+ optionalFields: ["roomType", "phone", "specialRequests"]
50
+ });
51
+
52
+ const customerServiceRoute = agent.createRoute({
53
+ title: "Customer Service",
54
+ description: "Help with booking issues",
55
+ conditions: ["User needs help with existing booking"],
56
+ requiredFields: ["customerName", "email"], // Minimal requirements
57
+ optionalFields: ["phone", "destination"]
26
58
  });
27
59
  ```
28
60
 
29
61
  ## Route Lifecycle
30
62
 
31
- Routes have a complete lifecycle from creation through execution to completion.
63
+ Routes have a complete lifecycle from creation through execution to completion based on data availability.
32
64
 
33
65
  ### Route Creation
34
66
 
35
- Routes are created using the agent's `createRoute()` method with type-safe data schemas.
67
+ Routes are created using the agent's `createRoute()` method with required fields specifications that reference the agent-level schema.
36
68
 
37
69
  ### Route Execution
38
70
 
39
- Routes are selected by the AI routing system based on user intent and conversation context.
71
+ Routes are selected by the AI routing system based on user intent and conversation context, with access to all agent-level data.
40
72
 
41
73
  ### Route Completion
42
74
 
43
- Routes complete when they reach the `END_ROUTE` step, triggering completion handlers and potential transitions.
75
+ Routes complete when all their required fields are present in the agent's collected data, regardless of which route collected the data. This enables flexible cross-route completion scenarios.
76
+
77
+ ```typescript
78
+ // Route completion evaluation
79
+ const isComplete = bookingRoute.isComplete(agent.getCollectedData());
80
+ const missingFields = bookingRoute.getMissingRequiredFields(agent.getCollectedData());
81
+ const progress = bookingRoute.getCompletionProgress(agent.getCollectedData()); // 0-1
82
+
83
+ console.log(`Booking route is ${Math.round(progress * 100)}% complete`);
84
+ if (missingFields.length > 0) {
85
+ console.log(`Still need: ${missingFields.join(', ')}`);
86
+ }
87
+ ```
44
88
 
45
89
  ## Route Transitions
46
90
 
47
- Routes can automatically transition to other routes upon completion using the `onComplete` configuration.
91
+ Routes can automatically transition to other routes upon completion using the `onComplete` configuration. With agent-level data, the target route may already have some of its required data.
48
92
 
49
93
  ```typescript
50
94
  const bookingRoute = agent.createRoute({
51
95
  title: "Hotel Booking",
96
+ requiredFields: ["destination", "checkIn", "checkOut", "guests", "customerName", "email"],
52
97
  onComplete: "Feedback Collection", // Transition to feedback route
53
98
  });
99
+
100
+ const feedbackRoute = agent.createRoute({
101
+ title: "Feedback Collection",
102
+ requiredFields: ["customerName", "email", "rating"], // Already has name and email from booking
103
+ optionalFields: ["comments"]
104
+ });
105
+
106
+ // When booking completes, feedback route is already 2/3 complete
54
107
  ```
55
108
 
56
109
  ## Best Practices
57
110
 
58
111
  - Use descriptive titles and conditions for better AI routing
59
- - Define comprehensive schemas for type safety
60
- - Implement appropriate completion handlers
61
- - Consider route transitions for multi-step workflows
112
+ - Define comprehensive agent-level schemas for type safety across all routes
113
+ - Specify minimal required fields for faster route completion
114
+ - Use optional fields to enhance user experience without blocking completion
115
+ - Implement appropriate completion handlers that leverage shared data
116
+ - Consider route transitions for multi-step workflows with data continuity
117
+ - Design routes that can benefit from cross-route data sharing
@@ -26,14 +26,14 @@ const smartRoute = agent
26
26
  initialStep: {
27
27
  prompt: "What's your name?",
28
28
  collect: ["name"],
29
- skipIf: (data) => data.name !== undefined, // Skip if name already known
29
+ skipIf: (data) => data.name !== undefined, // Skip if name already collected by any route
30
30
  },
31
31
  })
32
32
  .nextStep({
33
33
  prompt: "What's your email, {{name}}?",
34
34
  collect: ["email"],
35
- requires: ["name"], // Must have name to proceed
36
- skipIf: (data) => data.email !== undefined, // Skip if email already known
35
+ requires: ["name"], // Must have name from agent data to proceed
36
+ skipIf: (data) => data.email !== undefined, // Skip if email already collected by any route
37
37
  });
38
38
  ```
39
39
 
@@ -1,24 +1,25 @@
1
1
  # Steps
2
2
 
3
- Steps are the building blocks of conversational routes in @falai/agent. This document covers step configuration, data collection, and transition logic.
3
+ Steps are the building blocks of conversational routes in @falai/agent with agent-level data collection. This document covers step configuration, data collection into the agent schema, and transition logic based on agent data.
4
4
 
5
5
  ## Overview
6
6
 
7
7
  Steps represent individual moments in a conversation where the agent can:
8
8
 
9
9
  - Prompt the user for information
10
- - Collect structured data from responses
11
- - Execute tools or perform actions
12
- - Make decisions about conversation flow
10
+ - Collect structured data into the agent-level schema
11
+ - Execute tools that work with complete agent data
12
+ - Make decisions about conversation flow based on agent data
13
+ - Skip execution if required data is already available from other routes
13
14
 
14
15
  ## Step Configuration
15
16
 
16
17
  ```typescript
17
18
  const nameStep = bookingRoute.initialStep.nextStep({
18
19
  prompt: "What's your name?",
19
- collect: ["firstName", "lastName"],
20
+ collect: ["customerName"], // Collects into agent-level schema
20
21
  requires: [], // No prerequisites
21
- skipIf: (data) => data.firstName && data.lastName, // Skip if already collected
22
+ skipIf: (data) => data.customerName, // Skip if already collected by any route
22
23
  });
23
24
  ```
24
25
 
@@ -42,34 +43,57 @@ Steps that end the route using `END_ROUTE`.
42
43
 
43
44
  ## Data Collection
44
45
 
45
- Steps collect data through the `collect` array, which maps to the route's JSON schema.
46
+ Steps collect data through the `collect` array, which maps to the agent's JSON schema and is validated against it.
46
47
 
47
48
  ```typescript
48
49
  const contactStep = nameStep.nextStep({
49
50
  prompt: "What's your email and phone number?",
50
- collect: ["email", "phone"],
51
- requires: ["firstName"], // Must have name first
51
+ collect: ["email", "phone"], // Maps to agent schema fields
52
+ requires: ["customerName"], // Must have name first (from agent data)
52
53
  });
53
54
  ```
54
55
 
55
56
  ## Conditional Logic
56
57
 
57
- Steps support various conditional behaviors:
58
+ Steps support various conditional behaviors based on agent-level data:
58
59
 
59
- - `skipIf`: Skip the step if a condition is met
60
- - `requires`: Prerequisites that must be satisfied
60
+ - `skipIf`: Skip the step if a condition is met (evaluates against complete agent data)
61
+ - `requires`: Prerequisites that must be satisfied (checks agent data from any route)
61
62
  - `when`: AI-evaluated conditions for branching
62
63
 
63
64
  ## Tool Integration
64
65
 
65
- Steps can execute tools before generating AI responses:
66
+ Steps can execute tools that work with complete agent-level data:
66
67
 
67
68
  ```typescript
68
69
  const weatherStep = planningStep.nextStep({
69
70
  prompt: "I'll check the weather for your destination",
70
- tool: weatherLookupTool,
71
- requires: ["destination", "travelDate"],
71
+ tool: weatherLookupTool, // Tool receives complete agent data
72
+ requires: ["destination", "checkIn"], // Prerequisites from agent data
72
73
  });
74
+
75
+ // Tool implementation with agent data access
76
+ const weatherLookupTool: Tool<Context, [], WeatherData, HotelData> = {
77
+ id: "weather_lookup",
78
+ description: "Look up weather for destination",
79
+ parameters: { type: "object", properties: {} },
80
+ handler: async (toolContext) => {
81
+ const { data } = toolContext; // Complete agent data
82
+
83
+ if (!data.destination || !data.checkIn) {
84
+ return { data: undefined };
85
+ }
86
+
87
+ const weather = await getWeather(data.destination, data.checkIn);
88
+
89
+ return {
90
+ data: weather,
91
+ dataUpdate: {
92
+ weatherInfo: weather.summary // Update agent data
93
+ }
94
+ };
95
+ }
96
+ };
73
97
  ```
74
98
 
75
99
  ## Step Transitions
@@ -58,8 +58,9 @@ The system intelligently traverses step chains:
58
58
  All routing decisions consider:
59
59
 
60
60
  - **Conversation History**: Full dialogue context
61
- - **Collected Data**: What information has been gathered
62
- - **Session State**: Current route and step position
61
+ - **Agent-Level Data**: Centralized information gathered across all routes
62
+ - **Session State**: Current route and step position with cross-route data access
63
+ - **Route Completion**: Progress toward required fields for each route
63
64
  - **Agent Knowledge**: Guidelines, terms, and domain knowledge
64
65
 
65
66
  ## Route Selection API
@@ -107,20 +108,27 @@ The `getCandidateSteps()` method implements sophisticated logic:
107
108
  const candidates = routingEngine.getCandidateSteps(
108
109
  route, // Current route
109
110
  currentStep, // Current step (or null for route start)
110
- collectedData // Session data collected so far
111
+ agentData // Agent-level data collected across all routes
111
112
  );
112
113
  ```
113
114
 
114
115
  ### SkipIf Processing
115
116
 
116
- Steps are automatically filtered based on conditions:
117
+ Steps are automatically filtered based on agent-level data conditions:
117
118
 
118
119
  ```typescript
119
- // Step definition with skipIf
120
+ // Step definition with skipIf using agent data
120
121
  initialStep: {
121
122
  prompt: "What's your name?",
122
123
  collect: ["name"],
123
- skipIf: (data) => data.name !== undefined // Skip if name already collected
124
+ skipIf: (data) => data.name !== undefined // Skip if name already collected by any route
125
+ }
126
+
127
+ // Cross-route skipping example
128
+ const emailStep = {
129
+ prompt: "What's your email?",
130
+ collect: ["email"],
131
+ skipIf: (data) => data.email !== undefined // Skip if collected in different route
124
132
  }
125
133
  ```
126
134
 
@@ -155,8 +163,9 @@ const routingPrompt = await routingEngine.buildRoutingPrompt({
155
163
  Prompts include:
156
164
 
157
165
  - Agent identity and personality
158
- - Available routes with descriptions and conditions
159
- - Session context and collected data
166
+ - Available routes with descriptions and required fields
167
+ - Session context and agent-level collected data
168
+ - Route completion progress (e.g., "2/3 required fields collected")
160
169
  - Scoring guidelines (90-100 scale)
161
170
  - Conversation history and directives
162
171
 
@@ -169,7 +178,7 @@ const stepPrompt = await routingEngine.buildStepSelectionPrompt({
169
178
  route,
170
179
  currentStep,
171
180
  candidates,
172
- data: session.data,
181
+ data: agent.getCollectedData(), // Agent-level data
173
182
  history,
174
183
  lastMessage,
175
184
  agentOptions,