@falai/agent 0.5.5 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +88 -864
  2. package/dist/cjs/core/ResponseEngine.js +2 -2
  3. package/dist/cjs/core/ResponseEngine.js.map +1 -1
  4. package/dist/cjs/core/Route.d.ts +6 -1
  5. package/dist/cjs/core/Route.d.ts.map +1 -1
  6. package/dist/cjs/core/Route.js +19 -1
  7. package/dist/cjs/core/Route.js.map +1 -1
  8. package/dist/cjs/core/State.d.ts +1 -2
  9. package/dist/cjs/core/State.d.ts.map +1 -1
  10. package/dist/cjs/core/State.js +5 -6
  11. package/dist/cjs/core/State.js.map +1 -1
  12. package/dist/cjs/core/Transition.d.ts +2 -2
  13. package/dist/cjs/core/Transition.d.ts.map +1 -1
  14. package/dist/cjs/core/Transition.js +3 -2
  15. package/dist/cjs/core/Transition.js.map +1 -1
  16. package/dist/cjs/types/route.d.ts +15 -4
  17. package/dist/cjs/types/route.d.ts.map +1 -1
  18. package/dist/core/ResponseEngine.js +2 -2
  19. package/dist/core/ResponseEngine.js.map +1 -1
  20. package/dist/core/Route.d.ts +6 -1
  21. package/dist/core/Route.d.ts.map +1 -1
  22. package/dist/core/Route.js +19 -1
  23. package/dist/core/Route.js.map +1 -1
  24. package/dist/core/State.d.ts +1 -2
  25. package/dist/core/State.d.ts.map +1 -1
  26. package/dist/core/State.js +5 -6
  27. package/dist/core/State.js.map +1 -1
  28. package/dist/core/Transition.d.ts +2 -2
  29. package/dist/core/Transition.d.ts.map +1 -1
  30. package/dist/core/Transition.js +3 -2
  31. package/dist/core/Transition.js.map +1 -1
  32. package/dist/types/route.d.ts +15 -4
  33. package/dist/types/route.d.ts.map +1 -1
  34. package/docs/ADAPTERS.md +13 -1
  35. package/docs/API_REFERENCE.md +22 -25
  36. package/docs/ARCHITECTURE.md +18 -22
  37. package/docs/CONSTRUCTOR_OPTIONS.md +2 -2
  38. package/docs/CONTEXT_MANAGEMENT.md +1 -1
  39. package/docs/EXAMPLES.md +419 -0
  40. package/docs/GETTING_STARTED.md +1 -1
  41. package/docs/PERSISTENCE.md +3 -3
  42. package/examples/business-onboarding.ts +88 -70
  43. package/examples/company-qna-agent.ts +4 -4
  44. package/examples/custom-database-persistence.ts +2 -2
  45. package/examples/declarative-agent.ts +3 -3
  46. package/examples/extracted-data-modification.ts +1 -1
  47. package/examples/healthcare-agent.ts +24 -30
  48. package/examples/openai-agent.ts +1 -1
  49. package/examples/opensearch-persistence.ts +2 -2
  50. package/examples/persistent-onboarding.ts +2 -2
  51. package/examples/prisma-persistence.ts +3 -3
  52. package/examples/redis-persistence.ts +3 -3
  53. package/examples/travel-agent.ts +73 -96
  54. package/package.json +1 -1
  55. package/src/core/ResponseEngine.ts +2 -2
  56. package/src/core/Route.ts +34 -3
  57. package/src/core/State.ts +6 -13
  58. package/src/core/Transition.ts +6 -3
  59. 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
@@ -4,6 +4,18 @@ All adapters follow the **provider pattern** - no dependencies required in the p
4
4
 
5
5
  **NEW**: All adapters now support the new **Session State** pattern with automatic persistence of extracted data, current route/state, and conversation progress!
6
6
 
7
+ ### 🎯 Available Adapters
8
+
9
+ | Adapter | Use Case | Install |
10
+ | --------------------- | ---------------------------------- | -------------------------------------------- |
11
+ | **PrismaAdapter** | Type-safe ORM with migrations | `npm install @prisma/client` |
12
+ | **RedisAdapter** | Fast in-memory for real-time apps | `npm install ioredis` |
13
+ | **MongoAdapter** | Flexible document storage | `npm install mongodb` |
14
+ | **PostgreSQLAdapter** | Raw SQL with auto table creation | `npm install pg` |
15
+ | **SQLiteAdapter** | Lightweight local database | `npm install better-sqlite3` |
16
+ | **OpenSearchAdapter** | Full-text search & analytics | `npm install @opensearch-project/opensearch` |
17
+ | **MemoryAdapter** | Testing & development (no install) | Built-in (no dependencies) ✨ |
18
+
7
19
  ## ✅ Implemented Adapters
8
20
 
9
21
  ### 1. **PrismaAdapter**
@@ -102,7 +114,7 @@ const agent = new Agent({
102
114
  // Create a route with data extraction
103
115
  const route = agent.createRoute<YourDataType>({
104
116
  title: "My Route",
105
- gatherSchema: {
117
+ extractionSchema: {
106
118
  type: "object",
107
119
  properties: {
108
120
  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" },
@@ -0,0 +1,419 @@
1
+ # Examples
2
+
3
+ This directory contains production-ready examples demonstrating all features of `@falai/agent`.
4
+
5
+ ## 🚀 Getting Started Examples
6
+
7
+ ### 📋 [Declarative Agent](../examples/declarative-agent.ts)
8
+
9
+ **Perfect for:** Learning the full configuration API
10
+
11
+ Comprehensive example showing declarative agent configuration:
12
+
13
+ - ✅ Full constructor-based setup
14
+ - ✅ Terms, guidelines, capabilities, routes defined upfront
15
+ - ✅ Session state management with data extraction
16
+ - ✅ Custom IDs for routes, states, and tools
17
+ - ✅ Dynamic additions after construction
18
+
19
+ **Key concepts:** Declarative configuration, session state, data extraction schemas
20
+
21
+ ```typescript
22
+ const agent = new Agent({
23
+ name: "HealthBot",
24
+ ai: provider,
25
+ terms: [...],
26
+ guidelines: [...],
27
+ routes: [{
28
+ extractionSchema: { /* JSON Schema */ }
29
+ }]
30
+ });
31
+ ```
32
+
33
+ ---
34
+
35
+ ## 🏢 Real-World Applications
36
+
37
+ ### 🏢 [Business Onboarding](../examples/business-onboarding.ts)
38
+
39
+ **Perfect for:** Building complex multi-step workflows
40
+
41
+ Production-ready business onboarding with advanced patterns:
42
+
43
+ - ✅ Multi-step data collection flow
44
+ - ✅ Branching logic (physical vs online business)
45
+ - ✅ Tools with `contextUpdate` for automatic state management
46
+ - ✅ Both step-by-step and fluent chaining approaches
47
+ - ✅ Lifecycle hooks for persistence
48
+ - ✅ Dynamic route creation based on collected data
49
+
50
+ **Key concepts:** Complex flows, branching logic, context updates, lifecycle hooks
51
+
52
+ ```typescript
53
+ // Branching based on business type
54
+ const askPhysicalLocation = askLocation.transitionTo({
55
+ chatState: "Get physical store address",
56
+ condition: "User has a physical store",
57
+ });
58
+
59
+ const askOnlineLocation = askLocation.transitionTo({
60
+ chatState: "Get website and online support hours",
61
+ condition: "User does not have a physical store",
62
+ });
63
+ ```
64
+
65
+ ### ✈️ [Travel Agent](../examples/travel-agent.ts)
66
+
67
+ **Perfect for:** Multi-route systems with session state
68
+
69
+ Complete travel booking system featuring:
70
+
71
+ - ✅ Multi-step flight booking flow
72
+ - ✅ Data extraction with JSON Schema
73
+ - ✅ Session state tracking across turns
74
+ - ✅ Tools with data access via `extracted` context
75
+ - ✅ Alternative flow handling (booking vs status check)
76
+ - ✅ Route-specific guidelines
77
+
78
+ **Key concepts:** Session state, data extraction, multiple routes, tool data access
79
+
80
+ ```typescript
81
+ const searchFlights = defineTool(
82
+ "search_flights",
83
+ async ({ context, extracted }) => {
84
+ // Tool has access to extracted booking data
85
+ if (!extracted?.destination || !extracted?.departureDate) {
86
+ return { data: [] };
87
+ }
88
+ // Use extracted data to search
89
+ const flights = await searchAPI(extracted);
90
+ return { data: flights };
91
+ }
92
+ );
93
+ ```
94
+
95
+ ### 🏥 [Healthcare Assistant](../examples/healthcare-agent.ts)
96
+
97
+ **Perfect for:** Sensitive data handling and compliance
98
+
99
+ Healthcare-focused agent demonstrating:
100
+
101
+ - ✅ Appointment scheduling with validation
102
+ - ✅ Lab results retrieval
103
+ - ✅ Route-based disambiguation with conditions
104
+ - ✅ Sensitive data handling best practices
105
+ - ✅ Urgent case prioritization
106
+ - ✅ HIPAA-style security patterns
107
+
108
+ **Key concepts:** Data security, route disambiguation, validation, compliance
109
+
110
+ ---
111
+
112
+ ## ⚡ Advanced Features
113
+
114
+ ### ⚡ [Streaming Responses](../examples/streaming-agent.ts)
115
+
116
+ **Perfect for:** Real-time UX and better perceived performance
117
+
118
+ Real-time streaming responses:
119
+
120
+ - ✅ Stream responses from all providers (Anthropic, OpenAI, Gemini, OpenRouter)
121
+ - ✅ Real-time text generation with `respondStream`
122
+ - ✅ Cancellable streams with AbortSignal
123
+ - ✅ Access route, state, and tool information in final chunk
124
+ - ✅ 5 comprehensive examples covering different use cases
125
+
126
+ **Key concepts:** Streaming, real-time UX, cancellation
127
+
128
+ ```typescript
129
+ for await (const chunk of agent.respondStream({ history })) {
130
+ process.stdout.write(chunk.delta);
131
+
132
+ if (chunk.done) {
133
+ console.log("Route:", chunk.route?.title);
134
+ console.log("Extracted:", chunk.extracted);
135
+ }
136
+ }
137
+ ```
138
+
139
+ ### 🔐 [Domain Scoping](../examples/domain-scoping.ts)
140
+
141
+ **Perfect for:** Security-conscious applications
142
+
143
+ Control tool access per route for security:
144
+
145
+ - ✅ Organize tools into security domains
146
+ - ✅ Restrict which tools each route can use
147
+ - ✅ Prevent unauthorized tool calls
148
+ - ✅ Improve AI performance by reducing decision space
149
+ - ✅ Clear documentation of route capabilities
150
+
151
+ **Key concepts:** Security, tool isolation, domain organization
152
+
153
+ ```typescript
154
+ agent.addDomain("payment", { processPayment, refund });
155
+ agent.addDomain("user", { updateProfile, sendEmail });
156
+
157
+ // Checkout route can ONLY use payment tools
158
+ agent.createRoute({
159
+ title: "Checkout",
160
+ domains: ["payment"], // ← Security boundary
161
+ });
162
+ ```
163
+
164
+ ### 📜 [Rules & Prohibitions](../examples/rules-prohibitions.ts)
165
+
166
+ **Perfect for:** Multi-channel bots with different styles
167
+
168
+ Control agent behavior and communication style per route:
169
+
170
+ - ✅ Define absolute rules the agent must follow
171
+ - ✅ Set prohibitions for what agent must never do
172
+ - ✅ Different communication styles per route
173
+ - ✅ Perfect for multi-channel bots (WhatsApp, email, chat)
174
+ - ✅ Automatic enforcement without manual checking
175
+
176
+ **Key concepts:** Behavior control, tone management, channel-specific styling
177
+
178
+ ```typescript
179
+ agent.createRoute({
180
+ title: "WhatsApp Support",
181
+ rules: ["Keep messages under 2 lines", "Use max 1 emoji"],
182
+ prohibitions: ["Never send long paragraphs", "Don't over-explain"],
183
+ });
184
+
185
+ agent.createRoute({
186
+ title: "Email Support",
187
+ rules: ["Use professional tone", "Include clear next steps"],
188
+ prohibitions: ["No emojis", "Avoid slang"],
189
+ });
190
+ ```
191
+
192
+ ---
193
+
194
+ ## 💾 Persistence Examples
195
+
196
+ ### 💾 [Prisma Persistence](../examples/prisma-persistence.ts)
197
+
198
+ **Perfect for:** Production apps with relational databases
199
+
200
+ Auto-save sessions and messages with Prisma ORM:
201
+
202
+ - ✅ Provider pattern - simple as `new PrismaAdapter({ prisma })`
203
+ - ✅ Automatic session and message persistence
204
+ - ✅ Seamless lifecycle hook integration
205
+ - ✅ Type-safe database operations
206
+ - ✅ 3-step setup guide
207
+
208
+ **Key concepts:** Database persistence, Prisma ORM, auto-save
209
+
210
+ ```typescript
211
+ const agent = new Agent({
212
+ persistence: {
213
+ adapter: new PrismaAdapter({ prisma }),
214
+ autoSave: true,
215
+ userId: "user_123",
216
+ },
217
+ });
218
+ ```
219
+
220
+ ### ⚡ [Redis Persistence](../examples/redis-persistence.ts)
221
+
222
+ **Perfect for:** High-throughput real-time applications
223
+
224
+ Fast, in-memory persistence:
225
+
226
+ - ✅ Lightning-fast session storage
227
+ - ✅ Configurable TTLs for auto-cleanup
228
+ - ✅ Custom key prefixes
229
+ - ✅ Perfect for real-time chat applications
230
+ - ✅ Simple setup with ioredis
231
+
232
+ **Key concepts:** In-memory persistence, Redis, TTL management
233
+
234
+ ### 🔍 [OpenSearch Persistence](../examples/opensearch-persistence.ts)
235
+
236
+ **Perfect for:** Analytics and full-text search requirements
237
+
238
+ Full-text search and analytics-powered persistence:
239
+
240
+ - ✅ Built-in full-text search across all messages
241
+ - ✅ Powerful aggregations and analytics
242
+ - ✅ Compatible with Elasticsearch 7.x
243
+ - ✅ AWS OpenSearch Service ready
244
+ - ✅ Index management and optimization
245
+
246
+ **Key concepts:** Search, analytics, OpenSearch, Elasticsearch
247
+
248
+ ### 🗄️ [Custom Database Integration](../examples/custom-database-persistence.ts)
249
+
250
+ **Perfect for:** Integrating with existing database schemas
251
+
252
+ Manual session state management for existing schemas:
253
+
254
+ - ✅ Full control over database operations
255
+ - ✅ Works with any database (no adapter needed)
256
+ - ✅ Manual session state save/restore
257
+ - ✅ Perfect for integrating with existing schemas
258
+ - ✅ Complete example with validation hooks
259
+
260
+ **Key concepts:** Custom persistence, existing schemas, manual control
261
+
262
+ ---
263
+
264
+ ## 🔧 Context & State Management
265
+
266
+ ### 💾 [Persistent Onboarding Agent](../examples/persistent-onboarding.ts)
267
+
268
+ **Perfect for:** Multi-turn conversations with persistence
269
+
270
+ Multi-turn conversation with state persistence:
271
+
272
+ - ✅ Context lifecycle hooks for database integration
273
+ - ✅ Automatic persistence on context updates
274
+ - ✅ Factory pattern for agent creation
275
+ - ✅ Two approaches: lifecycle hooks vs context provider
276
+ - ✅ Complete onboarding flow across multiple turns
277
+
278
+ **Key concepts:** Context lifecycle, multi-turn conversations, factory pattern
279
+
280
+ ```typescript
281
+ const agent = new Agent({
282
+ hooks: {
283
+ beforeRespond: async (context) => {
284
+ return await database.loadContext(sessionId);
285
+ },
286
+ onContextUpdate: async (newContext) => {
287
+ await database.saveContext(sessionId, newContext);
288
+ },
289
+ },
290
+ });
291
+ ```
292
+
293
+ ### 🔄 [Extracted Data Modification](../examples/extracted-data-modification.ts)
294
+
295
+ **Perfect for:** Data validation and enrichment
296
+
297
+ Tools that validate and enrich extracted data:
298
+
299
+ - ✅ Tools can modify extracted data with `extractedUpdate`
300
+ - ✅ Data validation and enrichment patterns
301
+ - ✅ Flag-based conditional execution
302
+ - ✅ Error handling and data correction
303
+ - ✅ Multi-step data refinement
304
+
305
+ **Key concepts:** Data validation, enrichment, extractedUpdate, flags
306
+
307
+ ```typescript
308
+ const validateEmail = defineTool(
309
+ "validate_email",
310
+ async ({ extracted }) => {
311
+ const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(extracted.email);
312
+ return {
313
+ data: isValid,
314
+ extractedUpdate: {
315
+ emailValid: isValid, // Enrich extracted data
316
+ },
317
+ };
318
+ }
319
+ );
320
+ ```
321
+
322
+ ---
323
+
324
+ ## 🤖 Provider Examples
325
+
326
+ ### 🌐 [OpenAI Agent](../examples/openai-agent.ts)
327
+
328
+ **Perfect for:** Using GPT models
329
+
330
+ GPT-5 integration with backup models:
331
+
332
+ - ✅ OpenAI provider configuration
333
+ - ✅ Backup model fallback
334
+ - ✅ Retry configuration
335
+ - ✅ Weather checking example
336
+
337
+ **Key concepts:** OpenAI integration, model fallback
338
+
339
+ ### 🌐 Multiple Providers
340
+
341
+ See how different AI providers work:
342
+
343
+ - **[OpenAI Agent](../examples/openai-agent.ts)** - GPT-5 integration
344
+ - **[Healthcare Agent](../examples/healthcare-agent.ts)** - Claude 3.5 Sonnet (Anthropic)
345
+ - **[Travel Agent](../examples/travel-agent.ts)** - OpenRouter with backup models
346
+ - All examples include backup model configuration and retry settings
347
+
348
+ ---
349
+
350
+ ## 📚 Additional Examples
351
+
352
+ ### 📊 [Company Q&A Agent](../examples/company-qna-agent.ts)
353
+
354
+ **Perfect for:** Stateless question-answering systems
355
+
356
+ Simple Q&A agent with knowledge base:
357
+
358
+ - ✅ Stateless routes (no data extraction)
359
+ - ✅ Knowledge base integration
360
+ - ✅ Simple request-response pattern
361
+ - ✅ Perfect for FAQ bots
362
+
363
+ **Key concepts:** Stateless routing, Q&A patterns
364
+
365
+ ---
366
+
367
+ ## 🎯 How to Use These Examples
368
+
369
+ ### Running Examples
370
+
371
+ ```bash
372
+ # Install dependencies
373
+ bun install
374
+
375
+ # Set up environment variables
376
+ echo "GEMINI_API_KEY=your_key" > .env
377
+
378
+ # Run an example
379
+ bun examples/travel-agent.ts
380
+ ```
381
+
382
+ ### Learning Path
383
+
384
+ 1. **Start here:** [Declarative Agent](../examples/declarative-agent.ts) - Learn the basics
385
+ 2. **Simple flow:** [Travel Agent](../examples/travel-agent.ts) - Session state & extraction
386
+ 3. **Complex flow:** [Business Onboarding](../examples/business-onboarding.ts) - Branching & lifecycle
387
+ 4. **Add persistence:** [Prisma Persistence](../examples/prisma-persistence.ts) - Database integration
388
+ 5. **Add security:** [Domain Scoping](../examples/domain-scoping.ts) - Tool isolation
389
+
390
+ ### Quick Reference
391
+
392
+ | Example | Best For | Key Features |
393
+ |---------|----------|--------------|
394
+ | Declarative Agent | Learning basics | Full API coverage |
395
+ | Travel Agent | Session state | Multi-turn conversations |
396
+ | Business Onboarding | Complex flows | Branching, lifecycle hooks |
397
+ | Healthcare Agent | Security | Data validation, compliance |
398
+ | Streaming Agent | Real-time UX | Streaming responses |
399
+ | Domain Scoping | Security | Tool isolation |
400
+ | Prisma Persistence | Production | Database integration |
401
+
402
+ ---
403
+
404
+ ## 💡 Tips
405
+
406
+ **For Production:**
407
+ - Use [Prisma Persistence](../examples/prisma-persistence.ts) for relational data
408
+ - Use [Redis Persistence](../examples/redis-persistence.ts) for high-throughput
409
+ - Implement [Domain Scoping](../examples/domain-scoping.ts) for security
410
+ - Add [Rules & Prohibitions](../examples/rules-prohibitions.ts) for brand consistency
411
+
412
+ **For Development:**
413
+ - Start with [Declarative Agent](../examples/declarative-agent.ts)
414
+ - Use [Streaming Agent](../examples/streaming-agent.ts) for better UX
415
+ - Check [Custom Database Integration](../examples/custom-database-persistence.ts) for existing schemas
416
+
417
+ ---
418
+
419
+ **Need help?** Check the [full documentation](./README.md) or [open an issue](https://github.com/gusnips/falai/issues).
@@ -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" },