@falai/agent 0.5.5 → 0.6.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 (57) hide show
  1. package/dist/cjs/core/ResponseEngine.js +2 -2
  2. package/dist/cjs/core/ResponseEngine.js.map +1 -1
  3. package/dist/cjs/core/Route.d.ts +6 -1
  4. package/dist/cjs/core/Route.d.ts.map +1 -1
  5. package/dist/cjs/core/Route.js +19 -1
  6. package/dist/cjs/core/Route.js.map +1 -1
  7. package/dist/cjs/core/State.d.ts +1 -2
  8. package/dist/cjs/core/State.d.ts.map +1 -1
  9. package/dist/cjs/core/State.js +5 -6
  10. package/dist/cjs/core/State.js.map +1 -1
  11. package/dist/cjs/core/Transition.d.ts +2 -2
  12. package/dist/cjs/core/Transition.d.ts.map +1 -1
  13. package/dist/cjs/core/Transition.js +3 -2
  14. package/dist/cjs/core/Transition.js.map +1 -1
  15. package/dist/cjs/types/route.d.ts +15 -4
  16. package/dist/cjs/types/route.d.ts.map +1 -1
  17. package/dist/core/ResponseEngine.js +2 -2
  18. package/dist/core/ResponseEngine.js.map +1 -1
  19. package/dist/core/Route.d.ts +6 -1
  20. package/dist/core/Route.d.ts.map +1 -1
  21. package/dist/core/Route.js +19 -1
  22. package/dist/core/Route.js.map +1 -1
  23. package/dist/core/State.d.ts +1 -2
  24. package/dist/core/State.d.ts.map +1 -1
  25. package/dist/core/State.js +5 -6
  26. package/dist/core/State.js.map +1 -1
  27. package/dist/core/Transition.d.ts +2 -2
  28. package/dist/core/Transition.d.ts.map +1 -1
  29. package/dist/core/Transition.js +3 -2
  30. package/dist/core/Transition.js.map +1 -1
  31. package/dist/types/route.d.ts +15 -4
  32. package/dist/types/route.d.ts.map +1 -1
  33. package/docs/ADAPTERS.md +1 -1
  34. package/docs/API_REFERENCE.md +22 -25
  35. package/docs/ARCHITECTURE.md +18 -22
  36. package/docs/CONSTRUCTOR_OPTIONS.md +2 -2
  37. package/docs/CONTEXT_MANAGEMENT.md +1 -1
  38. package/docs/GETTING_STARTED.md +1 -1
  39. package/docs/PERSISTENCE.md +3 -3
  40. package/examples/business-onboarding.ts +86 -70
  41. package/examples/company-qna-agent.ts +4 -4
  42. package/examples/custom-database-persistence.ts +2 -2
  43. package/examples/declarative-agent.ts +3 -3
  44. package/examples/extracted-data-modification.ts +1 -1
  45. package/examples/healthcare-agent.ts +24 -30
  46. package/examples/openai-agent.ts +1 -1
  47. package/examples/opensearch-persistence.ts +2 -2
  48. package/examples/persistent-onboarding.ts +2 -2
  49. package/examples/prisma-persistence.ts +3 -3
  50. package/examples/redis-persistence.ts +3 -3
  51. package/examples/travel-agent.ts +73 -96
  52. package/package.json +1 -1
  53. package/src/core/ResponseEngine.ts +2 -2
  54. package/src/core/Route.ts +34 -3
  55. package/src/core/State.ts +6 -13
  56. package/src/core/Transition.ts +6 -3
  57. package/src/types/route.ts +15 -5
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/types/route.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;GAGG;AACH,MAAM,WAAW,YAAY,CAAC,UAAU,GAAG,OAAO;IAChD,qGAAqG;IACrG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,wCAAwC;IACxC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,gBAAgB,CAAC;IACvC,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,gBAAgB,CAAC;IACxC;;;OAGG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,QAAQ,GAAG,OAAO,EAAE,UAAU,GAAG,OAAO;IACtE,2FAA2F;IAC3F,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IAEnC,SAAS,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;IAC1C,mDAAmD;IACnD,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC;IACrD;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,QAAQ,GAAG,OAAO,EAAE,UAAU,GAAG,OAAO,CACxE,SAAQ,QAAQ;IAChB,iCAAiC;IACjC,YAAY,EAAE,CACZ,IAAI,EAAE,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,EAC1C,SAAS,CAAC,EAAE,MAAM,KACf,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;CAC7C"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/types/route.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;GAGG;AACH,MAAM,WAAW,YAAY,CAAC,UAAU,GAAG,OAAO;IAChD,qGAAqG;IACrG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,wCAAwC;IACxC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,gBAAgB,CAAC;IACvC,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,gBAAgB,CAAC;IACxC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAClC;;;;OAIG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,QAAQ,GAAG,OAAO,EAAE,UAAU,GAAG,OAAO;IACtE,2FAA2F;IAC3F,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IAEnC,SAAS,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;IAC1C,mDAAmD;IACnD,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC;IACrD;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,QAAQ,GAAG,OAAO,EAAE,UAAU,GAAG,OAAO,CACxE,SAAQ,QAAQ;IAChB,iCAAiC;IACjC,YAAY,EAAE,CACZ,IAAI,EAAE,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,KACvC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;CAC7C"}
package/docs/ADAPTERS.md CHANGED
@@ -102,7 +102,7 @@ const agent = new Agent({
102
102
  // Create a route with data extraction
103
103
  const route = agent.createRoute<YourDataType>({
104
104
  title: "My Route",
105
- gatherSchema: {
105
+ extractionSchema: {
106
106
  type: "object",
107
107
  properties: {
108
108
  field1: { type: "string" },
@@ -321,7 +321,7 @@ interface RouteOptions<TExtracted = unknown> {
321
321
  prohibitions?: string[]; // Absolute prohibitions the agent MUST NEVER do in this route
322
322
 
323
323
  // NEW: Schema-first data extraction
324
- gatherSchema?: {
324
+ extractionSchema?: {
325
325
  type: "object";
326
326
  properties: Record<string, any>;
327
327
  required?: string[];
@@ -395,7 +395,7 @@ Represents a state within a conversation route.
395
395
 
396
396
  #### Methods
397
397
 
398
- ##### `transitionTo(spec: TransitionSpec, condition?: string): TransitionResult`
398
+ ##### `transitionTo(spec: TransitionSpec): TransitionResult`
399
399
 
400
400
  Creates a transition from this state and returns a chainable result.
401
401
 
@@ -413,22 +413,23 @@ interface TransitionSpec<TExtracted = unknown> {
413
413
 
414
414
  // NEW: Prerequisites that must be met to enter this state
415
415
  requiredData?: string[];
416
+
417
+ // Optional: AI-evaluated text condition for this transition
418
+ condition?: string;
416
419
  }
417
420
 
418
421
  interface TransitionResult<TExtracted = unknown> {
419
422
  id: string; // State identifier
420
423
  routeId: string; // Route identifier
421
424
  transitionTo: (
422
- spec: TransitionSpec<TExtracted>,
423
- condition?: string // Optional: AI-evaluated text condition for this transition
425
+ spec: TransitionSpec<TExtracted>
424
426
  ) => TransitionResult<TExtracted>;
425
427
  }
426
428
  ```
427
429
 
428
430
  **Parameters:**
429
431
 
430
- - `spec`: The transition specification (see `TransitionSpec` above)
431
- - `condition` (optional): Human-readable condition text that the AI evaluates when selecting states. Use this to guide the AI's state selection based on conversation context. Examples: "Customer confirmed payment", "All required data collected", "User wants to modify order"
432
+ - `spec`: The transition specification (see `TransitionSpec` above). Can include an optional `condition` property for AI-evaluated state selection guidance.
432
433
 
433
434
  **Returns:** A `TransitionResult` that includes the target state's reference (`id`, `routeId`) and a `transitionTo` method for chaining additional transitions.
434
435
 
@@ -445,7 +446,7 @@ interface FlightData {
445
446
  // Create a data-driven route
446
447
  const flightRoute = agent.createRoute<FlightData>({
447
448
  title: "Book Flight",
448
- gatherSchema: {
449
+ extractionSchema: {
449
450
  type: "object",
450
451
  properties: {
451
452
  destination: { type: "string" },
@@ -457,24 +458,20 @@ const flightRoute = agent.createRoute<FlightData>({
457
458
  });
458
459
 
459
460
  // Approach 1: Step-by-step with data extraction and text conditions
460
- const askDestination = flightRoute.initialState.transitionTo(
461
- {
462
- chatState: "Ask where they want to fly",
463
- gather: ["destination"],
464
- skipIf: (extracted) => !!extracted.destination, // Skip if already have destination
465
- },
466
- "Customer hasn't specified destination yet" // AI-evaluated condition
467
- );
461
+ const askDestination = flightRoute.initialState.transitionTo({
462
+ chatState: "Ask where they want to fly",
463
+ gather: ["destination"],
464
+ skipIf: (extracted) => !!extracted.destination, // Skip if already have destination
465
+ condition: "Customer hasn't specified destination yet", // AI-evaluated condition
466
+ });
468
467
 
469
- const askDates = askDestination.transitionTo(
470
- {
471
- chatState: "Ask about travel dates",
472
- gather: ["departureDate"],
473
- skipIf: (extracted) => !!extracted.departureDate,
474
- requiredData: ["destination"], // Must have destination first
475
- },
476
- "Destination confirmed, need travel dates"
477
- );
468
+ const askDates = askDestination.transitionTo({
469
+ chatState: "Ask about travel dates",
470
+ gather: ["departureDate"],
471
+ skipIf: (extracted) => !!extracted.departureDate,
472
+ requiredData: ["destination"], // Must have destination first
473
+ condition: "Destination confirmed, need travel dates",
474
+ });
478
475
 
479
476
  const askPassengers = askDates.transitionTo({
480
477
  chatState: "How many passengers?",
@@ -1557,7 +1554,7 @@ interface SessionState<TExtracted = Record<string, unknown>> {
1557
1554
  **Key Features:**
1558
1555
 
1559
1556
  - **`id`** - Optional session identifier that persists across database operations
1560
- - **`extracted`** - Type-safe data collected via `gatherSchema`
1557
+ - **`extracted`** - Type-safe data collected via `extractionSchema`
1561
1558
  - **`currentRoute`** / **`currentState`** - Track conversation position
1562
1559
  - **`routeHistory`** - Full audit trail of route transitions
1563
1560
  - **`metadata`** - Custom data (timestamps, user info, etc.)
@@ -22,7 +22,7 @@ interface FlightData {
22
22
  const route = agent.createRoute<FlightData>({
23
23
  title: "Book Flight",
24
24
  description: "Help user book a flight",
25
- gatherSchema: {
25
+ extractionSchema: {
26
26
  type: "object",
27
27
  properties: {
28
28
  destination: { type: "string" },
@@ -112,26 +112,22 @@ Use TypeScript functions for deterministic flow control AND text conditions for
112
112
 
113
113
  ```typescript
114
114
  // State with smart bypassing based on extracted data
115
- const askDestination = route.initialState.transitionTo(
116
- {
117
- id: "ask_destination", // Optional: custom state ID
118
- chatState: "Ask where they want to fly",
119
- gather: ["destination"],
120
- skipIf: (extracted) => !!extracted.destination, // Code-based condition!
121
- },
122
- "Customer hasn't specified destination yet" // Text condition for AI
123
- );
115
+ const askDestination = route.initialState.transitionTo({
116
+ id: "ask_destination", // Optional: custom state ID
117
+ chatState: "Ask where they want to fly",
118
+ gather: ["destination"],
119
+ skipIf: (extracted) => !!extracted.destination, // Code-based condition!
120
+ condition: "Customer hasn't specified destination yet", // Text condition for AI
121
+ });
124
122
 
125
- const askDate = askDestination.transitionTo(
126
- {
127
- id: "ask_date", // Optional: custom state ID for easier tracking
128
- chatState: "Ask about travel dates",
129
- gather: ["departureDate"],
130
- skipIf: (extracted) => !!extracted.departureDate,
131
- requiredData: ["destination"], // Prerequisites
132
- },
133
- "Destination confirmed, need travel dates now"
134
- );
123
+ const askDate = askDestination.transitionTo({
124
+ id: "ask_date", // Optional: custom state ID for easier tracking
125
+ chatState: "Ask about travel dates",
126
+ gather: ["departureDate"],
127
+ skipIf: (extracted) => !!extracted.departureDate,
128
+ requiredData: ["destination"], // Prerequisites
129
+ condition: "Destination confirmed, need travel dates now",
130
+ });
135
131
  });
136
132
  ```
137
133
 
@@ -374,7 +370,7 @@ interface BookingData {
374
370
 
375
371
  const bookingRoute = agent.createRoute<BookingData>({
376
372
  title: "Flight Booking",
377
- gatherSchema: {
373
+ extractionSchema: {
378
374
  /* schema for all fields */
379
375
  },
380
376
  });
@@ -404,7 +400,7 @@ For simple question-answering without state:
404
400
  const qnaRoute = agent.createRoute({
405
401
  title: "Company Q&A",
406
402
  conditions: ["User asks about company"],
407
- // NO gatherSchema - stateless!
403
+ // NO extractionSchema - stateless!
408
404
  });
409
405
 
410
406
  // Just use initial state
@@ -103,7 +103,7 @@ const agent = new Agent<FlightBookingContext>({
103
103
  title: 'Book Flight',
104
104
  description: 'Help user book a flight',
105
105
  conditions: ['User wants to book a flight'],
106
- gatherSchema: {
106
+ extractionSchema: {
107
107
  type: 'object',
108
108
  properties: {
109
109
  destination: { type: 'string' },
@@ -175,7 +175,7 @@ interface RouteOptions<TExtracted = unknown> {
175
175
  prohibitions?: string[]; // Absolute prohibitions the agent MUST NEVER do
176
176
 
177
177
  // NEW: Schema-first data extraction
178
- gatherSchema?: {
178
+ extractionSchema?: {
179
179
  type: "object";
180
180
  properties: Record<string, any>;
181
181
  required?: string[];
@@ -182,7 +182,7 @@ interface FlightData {
182
182
 
183
183
  const route = agent.createRoute<FlightData>({
184
184
  title: "Book Flight",
185
- gatherSchema: {
185
+ extractionSchema: {
186
186
  type: "object",
187
187
  properties: {
188
188
  destination: { type: "string" },
@@ -86,7 +86,7 @@ const bookingRoute = agent.createRoute<FlightData>({
86
86
  title: "Book Flight",
87
87
  description: "Help user book a flight",
88
88
  conditions: ["User wants to book a flight"],
89
- gatherSchema: {
89
+ extractionSchema: {
90
90
  type: "object",
91
91
  properties: {
92
92
  destination: { type: "string" },
@@ -110,7 +110,7 @@ const agent = new Agent({
110
110
  // Create a route with data extraction
111
111
  const bookingRoute = agent.createRoute<BookingData>({
112
112
  title: "Book Flight",
113
- gatherSchema: {
113
+ extractionSchema: {
114
114
  type: "object",
115
115
  properties: {
116
116
  destination: { type: "string" },
@@ -273,7 +273,7 @@ await agent.updateContext({ preferences: { theme: "dark" } });
273
273
  The new architecture automatically saves and loads `SessionState<TExtracted>` which includes:
274
274
 
275
275
  - **Current route and state** - Track conversation progress
276
- - **Extracted data** - All data gathered via `gatherSchema` and `gather` fields
276
+ - **Extracted data** - All data gathered via `extractionSchema` and `gather` fields
277
277
  - **Route history** - History of route transitions
278
278
  - **Metadata** - Session timestamps and custom data
279
279
 
@@ -533,7 +533,7 @@ await persistence.saveMessage({
533
533
 
534
534
  1. ✅ **Use `createSessionWithState()`** - Get both database record and session state in one call
535
535
  2. ✅ **Enable `autoSave: true`** - Automatically persist session state after each response
536
- 3. ✅ **Define extraction schemas** - Use `gatherSchema` in routes for structured data collection
536
+ 3. ✅ **Define extraction schemas** - Use `extractionSchema` in routes for structured data collection
537
537
  4. ✅ **Pass session state** - Always pass `session` parameter to `agent.respond()`
538
538
  5. ✅ **Load session state** - Use `loadSessionState()` to resume conversations
539
539
  6. ✅ **Store extracted data** - Leverage `collectedData.extracted` for user input tracking
@@ -446,10 +446,10 @@ async function createBusinessOnboardingAgent(
446
446
  });
447
447
 
448
448
  // Step 1: Business basics - Save
449
- const saveBusiness = askBusiness.transitionTo(
450
- { toolState: saveBusinessInfo },
451
- "User provided company name, sector, and description"
452
- );
449
+ const saveBusiness = askBusiness.transitionTo({
450
+ toolState: saveBusinessInfo,
451
+ condition: "User provided company name, sector, and description",
452
+ });
453
453
 
454
454
  // Step 2: Products/Services - Ask
455
455
  const askProducts = saveBusiness.transitionTo({
@@ -458,10 +458,10 @@ async function createBusinessOnboardingAgent(
458
458
  });
459
459
 
460
460
  // Step 2: Products/Services - Save
461
- const saveProducts = askProducts.transitionTo(
462
- { toolState: saveProductsServices },
463
- "User listed products/services and target audience"
464
- );
461
+ const saveProducts = askProducts.transitionTo({
462
+ toolState: saveProductsServices,
463
+ condition: "User listed products/services and target audience",
464
+ });
465
465
 
466
466
  // Step 3: Location - Branch point
467
467
  const askLocation = saveProducts.transitionTo({
@@ -470,32 +470,28 @@ async function createBusinessOnboardingAgent(
470
470
  });
471
471
 
472
472
  // Step 3a: Physical store path
473
- const askPhysicalLocation = askLocation.transitionTo(
474
- {
475
- chatState:
476
- "I see! Since you have a physical presence, I need the complete address (street, number, city, and state) and business hours. This is important for your assistant to inform customers. (e.g., 'José Silva Street, 123, São Paulo - SP - Mon to Fri: 9am to 6pm')",
477
- },
478
- "User has a physical store"
479
- );
473
+ const askPhysicalLocation = askLocation.transitionTo({
474
+ chatState:
475
+ "I see! Since you have a physical presence, I need the complete address (street, number, city, and state) and business hours. This is important for your assistant to inform customers. (e.g., 'José Silva Street, 123, São Paulo - SP - Mon to Fri: 9am to 6pm')",
476
+ condition: "User has a physical store",
477
+ });
480
478
 
481
- const savePhysicalLocation = askPhysicalLocation.transitionTo(
482
- { toolState: saveLocationInfo },
483
- "User provided physical address"
484
- );
479
+ const savePhysicalLocation = askPhysicalLocation.transitionTo({
480
+ toolState: saveLocationInfo,
481
+ condition: "User provided physical address",
482
+ });
485
483
 
486
484
  // Step 3b: Online-only path
487
- const askOnlineLocation = askLocation.transitionTo(
488
- {
489
- chatState:
490
- "Perfect! Since it's online only, please share your main website or social media where customers can find you? And what are your support hours? (e.g., 'www.example.com - 24/7 support' or 'Instagram @mycompany - Mon to Fri: 9am-6pm')",
491
- },
492
- "User does not have a physical store"
493
- );
485
+ const askOnlineLocation = askLocation.transitionTo({
486
+ chatState:
487
+ "Perfect! Since it's online only, please share your main website or social media where customers can find you? And what are your support hours? (e.g., 'www.example.com - 24/7 support' or 'Instagram @mycompany - Mon to Fri: 9am-6pm')",
488
+ condition: "User does not have a physical store",
489
+ });
494
490
 
495
- const saveOnlineLocation = askOnlineLocation.transitionTo(
496
- { toolState: saveContactInfo },
497
- "User provided website/social media and support hours"
498
- );
491
+ const saveOnlineLocation = askOnlineLocation.transitionTo({
492
+ toolState: saveContactInfo,
493
+ condition: "User provided website/social media and support hours",
494
+ });
499
495
 
500
496
  // Step 4: Contact info (convergence point for physical stores)
501
497
  const askContact = savePhysicalLocation.transitionTo({
@@ -503,10 +499,10 @@ async function createBusinessOnboardingAgent(
503
499
  "Do you also have a website or social media? If yes, which one? (if not, you can skip by saying 'I don't have one')",
504
500
  });
505
501
 
506
- const saveContact = askContact.transitionTo(
507
- { toolState: saveContactInfo },
508
- "User provided website/social media"
509
- );
502
+ const saveContact = askContact.transitionTo({
503
+ toolState: saveContactInfo,
504
+ condition: "User provided website/social media",
505
+ });
510
506
 
511
507
  // Step 5: Payment info (convergence point from both paths)
512
508
  const askPayment = saveContact.transitionTo({
@@ -517,10 +513,10 @@ async function createBusinessOnboardingAgent(
517
513
  // Also connect online path to payment
518
514
  saveOnlineLocation.transitionTo({ state: askPayment });
519
515
 
520
- const savePayment = askPayment.transitionTo(
521
- { toolState: savePaymentInfo },
522
- "User provided payment methods or said not applicable"
523
- );
516
+ const savePayment = askPayment.transitionTo({
517
+ toolState: savePaymentInfo,
518
+ condition: "User provided payment methods or said not applicable",
519
+ });
524
520
 
525
521
  // Step 6: Suggest automatic routes
526
522
  const suggestRoutes = savePayment.transitionTo({
@@ -528,16 +524,16 @@ async function createBusinessOnboardingAgent(
528
524
  "Perfect! Now I'll create the essential routes. Based on what you told me, I'll automatically create:\n\n1. **Products and Services** - for when they ask what you offer\n2. **Pricing and Quotes** - for questions about prices\n3. **Payment Information** - payment methods and installments\n4. **Location and Contact** - address, website, and hours\n\nThese are the most important routes for any business. I'll create them automatically with the information you provided. Sound good?",
529
525
  });
530
526
 
531
- const createRoutes = suggestRoutes.transitionTo(
532
- { toolState: addConversationRoute },
533
- "User approved automatic route creation"
534
- );
527
+ const createRoutes = suggestRoutes.transitionTo({
528
+ toolState: addConversationRoute,
529
+ condition: "User approved automatic route creation",
530
+ });
535
531
 
536
532
  // Step 7: Review collected data
537
- const reviewData = createRoutes.transitionTo(
538
- { toolState: getCollectedData },
539
- "Routes created successfully"
540
- );
533
+ const reviewData = createRoutes.transitionTo({
534
+ toolState: getCollectedData,
535
+ condition: "Routes created successfully",
536
+ });
541
537
 
542
538
  // Step 8: Summary and options
543
539
  const summary = reviewData.transitionTo({
@@ -546,45 +542,65 @@ async function createBusinessOnboardingAgent(
546
542
  });
547
543
 
548
544
  // Step 9a: Add more routes
549
- const askCustomRoute = summary.transitionTo(
550
- {
551
- chatState:
552
- "Got it! Tell me about this additional route: what's the title, what kind of questions should it answer, and what keywords do customers use? (e.g., 'Warranty and Exchange - answers about warranty, exchange, and returns - keywords: warranty, exchange, return')",
553
- },
554
- "User wants to add more routes"
555
- );
545
+ const askCustomRoute = summary.transitionTo({
546
+ chatState:
547
+ "Got it! Tell me about this additional route: what's the title, what kind of questions should it answer, and what keywords do customers use? (e.g., 'Warranty and Exchange - answers about warranty, exchange, and returns - keywords: warranty, exchange, return')",
548
+ condition: "User wants to add more routes",
549
+ });
556
550
 
557
- const saveCustomRoute = askCustomRoute.transitionTo(
558
- { toolState: addConversationRoute },
559
- "User provided custom route information"
560
- );
551
+ const saveCustomRoute = askCustomRoute.transitionTo({
552
+ toolState: addConversationRoute,
553
+ condition: "User provided custom route information",
554
+ });
561
555
 
562
556
  // Loop back to summary after adding custom route
563
557
  saveCustomRoute.transitionTo({ state: summary });
564
558
 
565
559
  // Step 9b: Final confirmation
566
- const completion = summary.transitionTo(
567
- {
568
- chatState:
569
- "🎉 Perfect! Setup complete! Your WhatsApp assistant is ready and will use all this information to automatically serve your customers. If you have any questions or need adjustments, just let me know!",
570
- },
571
- "User confirmed everything is okay"
572
- );
560
+ const completion = summary.transitionTo({
561
+ chatState:
562
+ "🎉 Perfect! Setup complete! Your WhatsApp assistant is ready and will use all this information to automatically serve your customers. If you have any questions or need adjustments, just let me know!",
563
+ condition: "User confirmed everything is okay",
564
+ });
573
565
 
574
566
  completion.transitionTo({ state: END_ROUTE });
575
567
 
576
- // ==================== Alternative: Chained Approach ====================
577
- // For simpler linear flows, you can use chaining for conciseness:
568
+ // ==================== Alternative: Sequential Steps ====================
569
+ // For simpler linear flows, you can use the new sequential steps approach:
578
570
 
579
- // Example of a simple feedback collection route
580
- const feedbackRoute = agent.createRoute({
571
+ // Example 1: Using steps array (NEW!)
572
+ agent.createRoute({
581
573
  title: "Collect Feedback",
582
574
  description: "Quick feedback collection from completed onboarding",
583
575
  conditions: ["User wants to provide feedback"],
576
+ steps: [
577
+ {
578
+ id: "ask_rating",
579
+ chatState: "How would you rate your onboarding experience? (1-5 stars)",
580
+ },
581
+ {
582
+ id: "ask_liked_most",
583
+ chatState: "What did you like most about the process?",
584
+ },
585
+ {
586
+ id: "ask_improve",
587
+ chatState: "Is there anything we could improve?",
588
+ },
589
+ {
590
+ id: "thank_you",
591
+ chatState: "Thank you for your feedback! It helps us improve. 🙏",
592
+ },
593
+ ],
594
+ });
595
+
596
+ // Example 2: Traditional chaining approach (still supported)
597
+ const manualFeedbackRoute = agent.createRoute({
598
+ title: "Manual Feedback Route",
599
+ description: "Same flow using traditional chaining",
600
+ conditions: ["User wants manual feedback flow"],
584
601
  });
585
602
 
586
- // Beautiful fluent chaining for linear flows
587
- feedbackRoute.initialState
603
+ manualFeedbackRoute.initialState
588
604
  .transitionTo({
589
605
  id: "ask_rating",
590
606
  chatState: "How would you rate your onboarding experience? (1-5 stars)",
@@ -2,7 +2,7 @@
2
2
  * Example: Company Q&A Agent (Stateless, Knowledge-Based)
3
3
  *
4
4
  * This demonstrates:
5
- * 1. Schema-first architecture for stateless Q&A routes (no gatherSchema)
5
+ * 1. Schema-first architecture for stateless Q&A routes (no extractionSchema)
6
6
  * 2. Tools for context enrichment (not data extraction)
7
7
  * 3. Session state management even for stateless conversations
8
8
  * 4. Always-on routing with context awareness
@@ -234,7 +234,7 @@ const companyInfoRoute = agent.createRoute({
234
234
  "How many employees",
235
235
  "Where is the headquarters",
236
236
  ],
237
- // NO gatherSchema - stateless Q&A route
237
+ // NO extractionSchema - stateless Q&A route
238
238
  // Just use initial state with chatState for response generation
239
239
  });
240
240
 
@@ -250,7 +250,7 @@ const productInfoRoute = agent.createRoute({
250
250
  "What products do you offer",
251
251
  "Tell me about your widgets",
252
252
  ],
253
- // NO gatherSchema - just answering questions
253
+ // NO extractionSchema - just answering questions
254
254
  });
255
255
 
256
256
  // Initial state is enough - no transitions needed for simple Q&A
@@ -265,7 +265,7 @@ const policyRoute = agent.createRoute({
265
265
  "Shipping information",
266
266
  "Warranty questions",
267
267
  ],
268
- // NO gatherSchema
268
+ // NO extractionSchema
269
269
  });
270
270
 
271
271
  // Initial state is enough - no extra setup needed
@@ -146,7 +146,7 @@ async function example() {
146
146
  "User is a new customer",
147
147
  "User needs to set up their account",
148
148
  ],
149
- gatherSchema: {
149
+ extractionSchema: {
150
150
  type: "object",
151
151
  properties: {
152
152
  fullName: { type: "string" },
@@ -464,7 +464,7 @@ async function advancedExample() {
464
464
 
465
465
  const route = agent.createRoute<OnboardingData>({
466
466
  title: "Onboarding",
467
- gatherSchema: {
467
+ extractionSchema: {
468
468
  type: "object",
469
469
  properties: {
470
470
  fullName: { type: "string" },
@@ -190,7 +190,7 @@ const routes: RouteOptions[] = [
190
190
  title: "Schedule Appointment",
191
191
  description: "Helps the patient schedule an appointment",
192
192
  conditions: ["The patient wants to schedule an appointment"],
193
- gatherSchema: {
193
+ extractionSchema: {
194
194
  type: "object",
195
195
  properties: {
196
196
  appointmentType: {
@@ -232,7 +232,7 @@ const routes: RouteOptions[] = [
232
232
  title: "Check Lab Results",
233
233
  description: "Retrieves and explains patient lab results",
234
234
  conditions: ["The patient wants to see their lab results"],
235
- gatherSchema: {
235
+ extractionSchema: {
236
236
  type: "object",
237
237
  properties: {
238
238
  testType: {
@@ -264,7 +264,7 @@ const routes: RouteOptions[] = [
264
264
  title: "General Healthcare Questions",
265
265
  description: "Answer general healthcare questions",
266
266
  conditions: ["Patient asks general healthcare questions"],
267
- // No gatherSchema - stateless Q&A
267
+ // No extractionSchema - stateless Q&A
268
268
  },
269
269
  ];
270
270
 
@@ -251,7 +251,7 @@ const bookingRoute = agent.createRoute<FlightData>({
251
251
  "User wants to book a flight",
252
252
  "User mentions flying, traveling, or booking",
253
253
  ],
254
- gatherSchema: {
254
+ extractionSchema: {
255
255
  type: "object",
256
256
  properties: {
257
257
  destination: {