@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.
- package/dist/cjs/core/ResponseEngine.js +2 -2
- package/dist/cjs/core/ResponseEngine.js.map +1 -1
- package/dist/cjs/core/Route.d.ts +6 -1
- package/dist/cjs/core/Route.d.ts.map +1 -1
- package/dist/cjs/core/Route.js +19 -1
- package/dist/cjs/core/Route.js.map +1 -1
- package/dist/cjs/core/State.d.ts +1 -2
- package/dist/cjs/core/State.d.ts.map +1 -1
- package/dist/cjs/core/State.js +5 -6
- package/dist/cjs/core/State.js.map +1 -1
- package/dist/cjs/core/Transition.d.ts +2 -2
- package/dist/cjs/core/Transition.d.ts.map +1 -1
- package/dist/cjs/core/Transition.js +3 -2
- package/dist/cjs/core/Transition.js.map +1 -1
- package/dist/cjs/types/route.d.ts +15 -4
- package/dist/cjs/types/route.d.ts.map +1 -1
- package/dist/core/ResponseEngine.js +2 -2
- package/dist/core/ResponseEngine.js.map +1 -1
- package/dist/core/Route.d.ts +6 -1
- package/dist/core/Route.d.ts.map +1 -1
- package/dist/core/Route.js +19 -1
- package/dist/core/Route.js.map +1 -1
- package/dist/core/State.d.ts +1 -2
- package/dist/core/State.d.ts.map +1 -1
- package/dist/core/State.js +5 -6
- package/dist/core/State.js.map +1 -1
- package/dist/core/Transition.d.ts +2 -2
- package/dist/core/Transition.d.ts.map +1 -1
- package/dist/core/Transition.js +3 -2
- package/dist/core/Transition.js.map +1 -1
- package/dist/types/route.d.ts +15 -4
- package/dist/types/route.d.ts.map +1 -1
- package/docs/ADAPTERS.md +1 -1
- package/docs/API_REFERENCE.md +22 -25
- package/docs/ARCHITECTURE.md +18 -22
- package/docs/CONSTRUCTOR_OPTIONS.md +2 -2
- package/docs/CONTEXT_MANAGEMENT.md +1 -1
- package/docs/GETTING_STARTED.md +1 -1
- package/docs/PERSISTENCE.md +3 -3
- package/examples/business-onboarding.ts +86 -70
- package/examples/company-qna-agent.ts +4 -4
- package/examples/custom-database-persistence.ts +2 -2
- package/examples/declarative-agent.ts +3 -3
- package/examples/extracted-data-modification.ts +1 -1
- package/examples/healthcare-agent.ts +24 -30
- package/examples/openai-agent.ts +1 -1
- package/examples/opensearch-persistence.ts +2 -2
- package/examples/persistent-onboarding.ts +2 -2
- package/examples/prisma-persistence.ts +3 -3
- package/examples/redis-persistence.ts +3 -3
- package/examples/travel-agent.ts +73 -96
- package/package.json +1 -1
- package/src/core/ResponseEngine.ts +2 -2
- package/src/core/Route.ts +34 -3
- package/src/core/State.ts +6 -13
- package/src/core/Transition.ts +6 -3
- 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,
|
|
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
|
-
|
|
105
|
+
extractionSchema: {
|
|
106
106
|
type: "object",
|
|
107
107
|
properties: {
|
|
108
108
|
field1: { type: "string" },
|
package/docs/API_REFERENCE.md
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
463
|
-
|
|
464
|
-
|
|
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
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
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 `
|
|
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.)
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
178
|
+
extractionSchema?: {
|
|
179
179
|
type: "object";
|
|
180
180
|
properties: Record<string, any>;
|
|
181
181
|
required?: string[];
|
package/docs/GETTING_STARTED.md
CHANGED
|
@@ -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
|
-
|
|
89
|
+
extractionSchema: {
|
|
90
90
|
type: "object",
|
|
91
91
|
properties: {
|
|
92
92
|
destination: { type: "string" },
|
package/docs/PERSISTENCE.md
CHANGED
|
@@ -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
|
-
|
|
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 `
|
|
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 `
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
476
|
-
|
|
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
|
-
|
|
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
|
-
|
|
490
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
552
|
-
|
|
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
|
-
|
|
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
|
-
|
|
569
|
-
|
|
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:
|
|
577
|
-
// For simpler linear flows, you can use
|
|
568
|
+
// ==================== Alternative: Sequential Steps ====================
|
|
569
|
+
// For simpler linear flows, you can use the new sequential steps approach:
|
|
578
570
|
|
|
579
|
-
// Example
|
|
580
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
267
|
+
// No extractionSchema - stateless Q&A
|
|
268
268
|
},
|
|
269
269
|
];
|
|
270
270
|
|