@falai/agent 0.5.4 → 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/README.md +9 -4
- package/dist/cjs/core/Agent.d.ts +0 -5
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +75 -157
- package/dist/cjs/core/Agent.js.map +1 -1
- 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/RoutingEngine.d.ts +68 -2
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
- package/dist/cjs/core/RoutingEngine.js +416 -2
- package/dist/cjs/core/RoutingEngine.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/cjs/utils/event.d.ts +6 -0
- package/dist/cjs/utils/event.d.ts.map +1 -0
- package/dist/cjs/utils/event.js +20 -0
- package/dist/cjs/utils/event.js.map +1 -0
- package/dist/core/Agent.d.ts +0 -5
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +74 -156
- package/dist/core/Agent.js.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/RoutingEngine.d.ts +68 -2
- package/dist/core/RoutingEngine.d.ts.map +1 -1
- package/dist/core/RoutingEngine.js +416 -2
- package/dist/core/RoutingEngine.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/dist/utils/event.d.ts +6 -0
- package/dist/utils/event.d.ts.map +1 -0
- package/dist/utils/event.js +17 -0
- package/dist/utils/event.js.map +1 -0
- package/docs/ADAPTERS.md +1 -1
- package/docs/API_REFERENCE.md +15 -7
- package/docs/ARCHITECTURE.md +25 -5
- 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 +97 -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 +9 -3
- package/examples/openai-agent.ts +1 -1
- package/examples/opensearch-persistence.ts +2 -2
- package/examples/persistent-onboarding.ts +18 -12
- package/examples/prisma-persistence.ts +3 -3
- package/examples/redis-persistence.ts +3 -3
- package/examples/travel-agent.ts +23 -4
- package/package.json +1 -1
- package/src/core/Agent.ts +78 -227
- package/src/core/ResponseEngine.ts +2 -2
- package/src/core/Route.ts +34 -3
- package/src/core/RoutingEngine.ts +663 -2
- package/src/core/State.ts +6 -13
- package/src/core/Transition.ts +6 -3
- package/src/types/route.ts +15 -5
- package/src/utils/event.ts +16 -0
|
@@ -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,55 +542,79 @@ 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({
|
|
605
|
+
id: "ask_rating",
|
|
589
606
|
chatState: "How would you rate your onboarding experience? (1-5 stars)",
|
|
590
607
|
})
|
|
591
608
|
.transitionTo({
|
|
609
|
+
id: "ask_liked_most",
|
|
592
610
|
chatState: "What did you like most about the process?",
|
|
593
611
|
})
|
|
594
612
|
.transitionTo({
|
|
613
|
+
id: "ask_improve",
|
|
595
614
|
chatState: "Is there anything we could improve?",
|
|
596
615
|
})
|
|
597
616
|
.transitionTo({
|
|
617
|
+
id: "thank_you",
|
|
598
618
|
chatState: "Thank you for your feedback! It helps us improve. 🙏",
|
|
599
619
|
})
|
|
600
620
|
.transitionTo({ state: END_ROUTE });
|
|
@@ -603,38 +623,45 @@ async function createBusinessOnboardingAgent(
|
|
|
603
623
|
|
|
604
624
|
agent
|
|
605
625
|
.createGuideline({
|
|
626
|
+
id: "guideline_confused",
|
|
606
627
|
condition: "User seems confused or doesn't understand something",
|
|
607
628
|
action:
|
|
608
629
|
"Be patient and provide practical examples of what you need. E.g., 'José Silva Street, 123, São Paulo - SP' for address",
|
|
609
630
|
})
|
|
610
631
|
.createGuideline({
|
|
632
|
+
id: "guideline_incomplete",
|
|
611
633
|
condition: "User provides incomplete or very vague information",
|
|
612
634
|
action:
|
|
613
635
|
"Politely ask for the missing specific details. E.g., 'You mentioned the address, but what's the city and state?'",
|
|
614
636
|
})
|
|
615
637
|
.createGuideline({
|
|
638
|
+
id: "guideline_skip",
|
|
616
639
|
condition:
|
|
617
640
|
"User wants to skip information saying they don't have it or it doesn't apply",
|
|
618
641
|
action:
|
|
619
642
|
"Be smart: if the information is critical for their business type (e.g., address for physical store, website for e-commerce), explain the importance. If not critical, accept it and move forward saying 'no problem, that's fine'",
|
|
620
643
|
})
|
|
621
644
|
.createGuideline({
|
|
645
|
+
id: "guideline_physical_online",
|
|
622
646
|
condition: "User has physical store but said online-only or vice versa",
|
|
623
647
|
action:
|
|
624
648
|
"Adjust the flow dynamically: if they have a physical store, prioritize address and hours. If online-only, prioritize website/social media and digital support hours. Don't ask for irrelevant information",
|
|
625
649
|
})
|
|
626
650
|
.createGuideline({
|
|
651
|
+
id: "guideline_why",
|
|
627
652
|
condition: "User asks why they need to provide certain information",
|
|
628
653
|
action:
|
|
629
654
|
"Explain practically: 'This information will help your assistant automatically answer customers when they ask about this. E.g., when they ask about payment methods, the assistant will inform automatically'",
|
|
630
655
|
})
|
|
631
656
|
.createGuideline({
|
|
657
|
+
id: "guideline_edit",
|
|
632
658
|
condition:
|
|
633
659
|
"User wants to edit or correct something they already provided",
|
|
634
660
|
action:
|
|
635
661
|
"Accept promptly and update the information: 'Of course! I'll update to...'. Use the appropriate tool to save the correction",
|
|
636
662
|
})
|
|
637
663
|
.createGuideline({
|
|
664
|
+
id: "guideline_unrelated",
|
|
638
665
|
condition: "User asks a question unrelated to onboarding",
|
|
639
666
|
action:
|
|
640
667
|
"Answer briefly and redirect: 'I understand, but let's finish the setup first? We're almost there!'",
|
|
@@ -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
|
|
|
@@ -130,7 +130,7 @@ async function createHealthcareAgent() {
|
|
|
130
130
|
title: "Schedule an Appointment",
|
|
131
131
|
description: "Helps the patient find a time for their appointment.",
|
|
132
132
|
conditions: ["The patient wants to schedule an appointment"],
|
|
133
|
-
|
|
133
|
+
extractionSchema: {
|
|
134
134
|
type: "object",
|
|
135
135
|
properties: {
|
|
136
136
|
appointmentReason: {
|
|
@@ -165,6 +165,7 @@ async function createHealthcareAgent() {
|
|
|
165
165
|
chatState: "Ask what the patient needs an appointment for",
|
|
166
166
|
gather: ["appointmentReason"],
|
|
167
167
|
skipIf: (extracted) => !!extracted.appointmentReason,
|
|
168
|
+
condition: "Patient hasn't specified reason for appointment yet",
|
|
168
169
|
});
|
|
169
170
|
|
|
170
171
|
// State 2: Check urgency and show available slots
|
|
@@ -173,6 +174,7 @@ async function createHealthcareAgent() {
|
|
|
173
174
|
gather: ["urgency"],
|
|
174
175
|
skipIf: (extracted) => !!extracted.urgency,
|
|
175
176
|
requiredData: ["appointmentReason"],
|
|
177
|
+
condition: "Reason provided, now assess urgency level",
|
|
176
178
|
});
|
|
177
179
|
|
|
178
180
|
const showSlots = checkUrgency.transitionTo({
|
|
@@ -203,13 +205,17 @@ async function createHealthcareAgent() {
|
|
|
203
205
|
const schedule = confirmDetails.transitionTo({
|
|
204
206
|
toolState: scheduleAppointment,
|
|
205
207
|
requiredData: ["appointmentReason", "preferredTime", "preferredDate"],
|
|
208
|
+
condition: "All details confirmed, book the appointment",
|
|
206
209
|
});
|
|
207
210
|
|
|
208
211
|
const confirmation = schedule.transitionTo({
|
|
209
212
|
chatState: "Confirm the appointment has been scheduled",
|
|
210
213
|
});
|
|
211
214
|
|
|
212
|
-
confirmation.transitionTo({
|
|
215
|
+
confirmation.transitionTo({
|
|
216
|
+
state: END_ROUTE,
|
|
217
|
+
condition: "Appointment booked successfully",
|
|
218
|
+
});
|
|
213
219
|
|
|
214
220
|
// Alternative path: no times work - show later slots
|
|
215
221
|
const laterSlots = presentTimes.transitionTo({
|
|
@@ -238,7 +244,7 @@ async function createHealthcareAgent() {
|
|
|
238
244
|
title: "Lab Results",
|
|
239
245
|
description: "Retrieves the patient's lab results and explains them.",
|
|
240
246
|
conditions: ["The patient wants to see their lab results"],
|
|
241
|
-
|
|
247
|
+
extractionSchema: {
|
|
242
248
|
type: "object",
|
|
243
249
|
properties: {
|
|
244
250
|
testType: {
|
package/examples/openai-agent.ts
CHANGED
|
@@ -112,7 +112,7 @@ async function main() {
|
|
|
112
112
|
title: "Check Weather",
|
|
113
113
|
description: "Help user check weather for a location",
|
|
114
114
|
conditions: ["User wants to know the weather"],
|
|
115
|
-
|
|
115
|
+
extractionSchema: {
|
|
116
116
|
type: "object",
|
|
117
117
|
properties: {
|
|
118
118
|
location: {
|
|
@@ -105,7 +105,7 @@ async function example() {
|
|
|
105
105
|
"User reports an issue or problem",
|
|
106
106
|
"User is dissatisfied",
|
|
107
107
|
],
|
|
108
|
-
|
|
108
|
+
extractionSchema: {
|
|
109
109
|
type: "object",
|
|
110
110
|
properties: {
|
|
111
111
|
category: {
|
|
@@ -337,7 +337,7 @@ async function analyticsExample() {
|
|
|
337
337
|
|
|
338
338
|
const ticketRoute = agent.createRoute<TicketData>({
|
|
339
339
|
title: "Analyze Support Ticket",
|
|
340
|
-
|
|
340
|
+
extractionSchema: {
|
|
341
341
|
type: "object",
|
|
342
342
|
properties: {
|
|
343
343
|
ticketType: { type: "string" },
|
|
@@ -244,7 +244,7 @@ async function createPersistentOnboardingAgent(sessionId: string) {
|
|
|
244
244
|
title: "Business Onboarding",
|
|
245
245
|
description: "Guide user through business information collection",
|
|
246
246
|
conditions: ["User is onboarding their business"],
|
|
247
|
-
|
|
247
|
+
extractionSchema: {
|
|
248
248
|
type: "object",
|
|
249
249
|
properties: {
|
|
250
250
|
businessName: {
|
|
@@ -269,18 +269,24 @@ async function createPersistentOnboardingAgent(sessionId: string) {
|
|
|
269
269
|
});
|
|
270
270
|
|
|
271
271
|
// State 1: Gather business name and description
|
|
272
|
-
const gatherBusinessInfo = onboardingRoute.initialState.transitionTo(
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
272
|
+
const gatherBusinessInfo = onboardingRoute.initialState.transitionTo(
|
|
273
|
+
{
|
|
274
|
+
chatState: "Ask for business name and a brief description",
|
|
275
|
+
gather: ["businessName", "businessDescription"],
|
|
276
|
+
skipIf: (extracted) =>
|
|
277
|
+
!!extracted.businessName && !!extracted.businessDescription,
|
|
278
|
+
},
|
|
279
|
+
"Need to collect basic business information first"
|
|
280
|
+
);
|
|
278
281
|
|
|
279
282
|
// State 2: Save business info (tool execution)
|
|
280
|
-
const saveBusiness = gatherBusinessInfo.transitionTo(
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
283
|
+
const saveBusiness = gatherBusinessInfo.transitionTo(
|
|
284
|
+
{
|
|
285
|
+
toolState: saveBusinessInfo,
|
|
286
|
+
requiredData: ["businessName", "businessDescription"],
|
|
287
|
+
},
|
|
288
|
+
"Business name and description provided, save to database"
|
|
289
|
+
);
|
|
284
290
|
|
|
285
291
|
// State 3: Gather industry
|
|
286
292
|
const gatherIndustry = saveBusiness.transitionTo({
|
|
@@ -497,7 +503,7 @@ async function main() {
|
|
|
497
503
|
* - Always-on routing respects intent changes
|
|
498
504
|
*
|
|
499
505
|
* ✅ PATTERN 2: Schema-First Data Extraction
|
|
500
|
-
* -
|
|
506
|
+
* - extractionSchema: Define data contracts upfront
|
|
501
507
|
* - Type-safe extraction throughout conversation
|
|
502
508
|
* - skipIf functions for deterministic state logic
|
|
503
509
|
* - requiredData arrays for prerequisites
|
|
@@ -96,7 +96,7 @@ async function example() {
|
|
|
96
96
|
"User wants to book a flight",
|
|
97
97
|
"User mentions travel, flying, or booking tickets",
|
|
98
98
|
],
|
|
99
|
-
|
|
99
|
+
extractionSchema: {
|
|
100
100
|
type: "object",
|
|
101
101
|
properties: {
|
|
102
102
|
destination: {
|
|
@@ -413,7 +413,7 @@ async function advancedExample() {
|
|
|
413
413
|
const onboardingRoute = agent.createRoute<OnboardingData>({
|
|
414
414
|
title: "User Onboarding",
|
|
415
415
|
description: "Collect user information for account setup",
|
|
416
|
-
|
|
416
|
+
extractionSchema: {
|
|
417
417
|
type: "object",
|
|
418
418
|
properties: {
|
|
419
419
|
fullName: { type: "string" },
|
|
@@ -514,7 +514,7 @@ async function quickStart() {
|
|
|
514
514
|
// Create a simple contact form route
|
|
515
515
|
const contactRoute = agent.createRoute<ContactFormData>({
|
|
516
516
|
title: "Contact Form",
|
|
517
|
-
|
|
517
|
+
extractionSchema: {
|
|
518
518
|
type: "object",
|
|
519
519
|
properties: {
|
|
520
520
|
name: { type: "string" },
|
|
@@ -88,7 +88,7 @@ async function example() {
|
|
|
88
88
|
"User wants to report a problem",
|
|
89
89
|
"User mentions support, help, or issue",
|
|
90
90
|
],
|
|
91
|
-
|
|
91
|
+
extractionSchema: {
|
|
92
92
|
type: "object",
|
|
93
93
|
properties: {
|
|
94
94
|
issue: {
|
|
@@ -286,7 +286,7 @@ async function highThroughputExample() {
|
|
|
286
286
|
// Simple chat route that extracts topic and sentiment
|
|
287
287
|
const chatRoute = agent.createRoute<QuickChatData>({
|
|
288
288
|
title: "General Chat",
|
|
289
|
-
|
|
289
|
+
extractionSchema: {
|
|
290
290
|
type: "object",
|
|
291
291
|
properties: {
|
|
292
292
|
topic: {
|
|
@@ -364,7 +364,7 @@ async function sessionRecoveryExample() {
|
|
|
364
364
|
|
|
365
365
|
const orderRoute = agent.createRoute<OrderData>({
|
|
366
366
|
title: "Place Order",
|
|
367
|
-
|
|
367
|
+
extractionSchema: {
|
|
368
368
|
type: "object",
|
|
369
369
|
properties: {
|
|
370
370
|
productId: { type: "string" },
|