@falai/agent 0.5.4 → 0.5.5
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/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/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/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/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/API_REFERENCE.md +24 -13
- package/docs/ARCHITECTURE.md +38 -14
- package/examples/business-onboarding.ts +11 -0
- package/examples/healthcare-agent.ts +28 -16
- package/examples/persistent-onboarding.ts +16 -10
- package/examples/travel-agent.ts +94 -52
- package/package.json +1 -1
- package/src/core/Agent.ts +78 -227
- package/src/core/RoutingEngine.ts +663 -2
- package/src/utils/event.ts +16 -0
|
@@ -586,15 +586,19 @@ async function createBusinessOnboardingAgent(
|
|
|
586
586
|
// Beautiful fluent chaining for linear flows
|
|
587
587
|
feedbackRoute.initialState
|
|
588
588
|
.transitionTo({
|
|
589
|
+
id: "ask_rating",
|
|
589
590
|
chatState: "How would you rate your onboarding experience? (1-5 stars)",
|
|
590
591
|
})
|
|
591
592
|
.transitionTo({
|
|
593
|
+
id: "ask_liked_most",
|
|
592
594
|
chatState: "What did you like most about the process?",
|
|
593
595
|
})
|
|
594
596
|
.transitionTo({
|
|
597
|
+
id: "ask_improve",
|
|
595
598
|
chatState: "Is there anything we could improve?",
|
|
596
599
|
})
|
|
597
600
|
.transitionTo({
|
|
601
|
+
id: "thank_you",
|
|
598
602
|
chatState: "Thank you for your feedback! It helps us improve. 🙏",
|
|
599
603
|
})
|
|
600
604
|
.transitionTo({ state: END_ROUTE });
|
|
@@ -603,38 +607,45 @@ async function createBusinessOnboardingAgent(
|
|
|
603
607
|
|
|
604
608
|
agent
|
|
605
609
|
.createGuideline({
|
|
610
|
+
id: "guideline_confused",
|
|
606
611
|
condition: "User seems confused or doesn't understand something",
|
|
607
612
|
action:
|
|
608
613
|
"Be patient and provide practical examples of what you need. E.g., 'José Silva Street, 123, São Paulo - SP' for address",
|
|
609
614
|
})
|
|
610
615
|
.createGuideline({
|
|
616
|
+
id: "guideline_incomplete",
|
|
611
617
|
condition: "User provides incomplete or very vague information",
|
|
612
618
|
action:
|
|
613
619
|
"Politely ask for the missing specific details. E.g., 'You mentioned the address, but what's the city and state?'",
|
|
614
620
|
})
|
|
615
621
|
.createGuideline({
|
|
622
|
+
id: "guideline_skip",
|
|
616
623
|
condition:
|
|
617
624
|
"User wants to skip information saying they don't have it or it doesn't apply",
|
|
618
625
|
action:
|
|
619
626
|
"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
627
|
})
|
|
621
628
|
.createGuideline({
|
|
629
|
+
id: "guideline_physical_online",
|
|
622
630
|
condition: "User has physical store but said online-only or vice versa",
|
|
623
631
|
action:
|
|
624
632
|
"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
633
|
})
|
|
626
634
|
.createGuideline({
|
|
635
|
+
id: "guideline_why",
|
|
627
636
|
condition: "User asks why they need to provide certain information",
|
|
628
637
|
action:
|
|
629
638
|
"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
639
|
})
|
|
631
640
|
.createGuideline({
|
|
641
|
+
id: "guideline_edit",
|
|
632
642
|
condition:
|
|
633
643
|
"User wants to edit or correct something they already provided",
|
|
634
644
|
action:
|
|
635
645
|
"Accept promptly and update the information: 'Of course! I'll update to...'. Use the appropriate tool to save the correction",
|
|
636
646
|
})
|
|
637
647
|
.createGuideline({
|
|
648
|
+
id: "guideline_unrelated",
|
|
638
649
|
condition: "User asks a question unrelated to onboarding",
|
|
639
650
|
action:
|
|
640
651
|
"Answer briefly and redirect: 'I understand, but let's finish the setup first? We're almost there!'",
|
|
@@ -161,19 +161,25 @@ async function createHealthcareAgent() {
|
|
|
161
161
|
});
|
|
162
162
|
|
|
163
163
|
// State 1: Gather appointment reason
|
|
164
|
-
const gatherReason = schedulingRoute.initialState.transitionTo(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
164
|
+
const gatherReason = schedulingRoute.initialState.transitionTo(
|
|
165
|
+
{
|
|
166
|
+
chatState: "Ask what the patient needs an appointment for",
|
|
167
|
+
gather: ["appointmentReason"],
|
|
168
|
+
skipIf: (extracted) => !!extracted.appointmentReason,
|
|
169
|
+
},
|
|
170
|
+
"Patient hasn't specified reason for appointment yet"
|
|
171
|
+
);
|
|
169
172
|
|
|
170
173
|
// State 2: Check urgency and show available slots
|
|
171
|
-
const checkUrgency = gatherReason.transitionTo(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
const checkUrgency = gatherReason.transitionTo(
|
|
175
|
+
{
|
|
176
|
+
chatState: "Check if this is urgent and show available slots",
|
|
177
|
+
gather: ["urgency"],
|
|
178
|
+
skipIf: (extracted) => !!extracted.urgency,
|
|
179
|
+
requiredData: ["appointmentReason"],
|
|
180
|
+
},
|
|
181
|
+
"Reason provided, now assess urgency level"
|
|
182
|
+
);
|
|
177
183
|
|
|
178
184
|
const showSlots = checkUrgency.transitionTo({
|
|
179
185
|
toolState: getUpcomingSlots,
|
|
@@ -200,16 +206,22 @@ async function createHealthcareAgent() {
|
|
|
200
206
|
requiredData: ["appointmentReason", "preferredTime", "preferredDate"],
|
|
201
207
|
});
|
|
202
208
|
|
|
203
|
-
const schedule = confirmDetails.transitionTo(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
209
|
+
const schedule = confirmDetails.transitionTo(
|
|
210
|
+
{
|
|
211
|
+
toolState: scheduleAppointment,
|
|
212
|
+
requiredData: ["appointmentReason", "preferredTime", "preferredDate"],
|
|
213
|
+
},
|
|
214
|
+
"All details confirmed, book the appointment"
|
|
215
|
+
);
|
|
207
216
|
|
|
208
217
|
const confirmation = schedule.transitionTo({
|
|
209
218
|
chatState: "Confirm the appointment has been scheduled",
|
|
210
219
|
});
|
|
211
220
|
|
|
212
|
-
confirmation.transitionTo(
|
|
221
|
+
confirmation.transitionTo(
|
|
222
|
+
{ state: END_ROUTE },
|
|
223
|
+
"Appointment booked successfully"
|
|
224
|
+
);
|
|
213
225
|
|
|
214
226
|
// Alternative path: no times work - show later slots
|
|
215
227
|
const laterSlots = presentTimes.transitionTo({
|
|
@@ -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({
|
package/examples/travel-agent.ts
CHANGED
|
@@ -270,55 +270,85 @@ async function createTravelAgent() {
|
|
|
270
270
|
});
|
|
271
271
|
|
|
272
272
|
// Build the route flow with data extraction and smart state progression
|
|
273
|
-
const askDestination = flightBookingRoute.initialState.transitionTo(
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
273
|
+
const askDestination = flightBookingRoute.initialState.transitionTo(
|
|
274
|
+
{
|
|
275
|
+
chatState: "Ask about the destination",
|
|
276
|
+
gather: ["destination"],
|
|
277
|
+
skipIf: (extracted) => !!extracted.destination,
|
|
278
|
+
},
|
|
279
|
+
"Customer needs to specify their travel destination"
|
|
280
|
+
);
|
|
278
281
|
|
|
279
|
-
const enrichDestination = askDestination.transitionTo(
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
282
|
+
const enrichDestination = askDestination.transitionTo(
|
|
283
|
+
{
|
|
284
|
+
toolState: lookupDestinationCode,
|
|
285
|
+
requiredData: ["destination"],
|
|
286
|
+
},
|
|
287
|
+
"Destination provided, lookup airport code"
|
|
288
|
+
);
|
|
283
289
|
|
|
284
|
-
const askDates = enrichDestination.transitionTo(
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
+
const askDates = enrichDestination.transitionTo(
|
|
291
|
+
{
|
|
292
|
+
chatState: "Ask about preferred travel dates",
|
|
293
|
+
gather: ["departureDate"],
|
|
294
|
+
skipIf: (extracted) => !!extracted.departureDate,
|
|
295
|
+
requiredData: ["destination"],
|
|
296
|
+
},
|
|
297
|
+
"Destination confirmed, need travel dates"
|
|
298
|
+
);
|
|
290
299
|
|
|
291
|
-
const askPassengers = askDates.transitionTo(
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
300
|
+
const askPassengers = askDates.transitionTo(
|
|
301
|
+
{
|
|
302
|
+
chatState: "Ask for number of passengers",
|
|
303
|
+
gather: ["passengers"],
|
|
304
|
+
skipIf: (extracted) => !!extracted.passengers,
|
|
305
|
+
requiredData: ["destination", "departureDate"],
|
|
306
|
+
},
|
|
307
|
+
"Dates confirmed, need passenger count"
|
|
308
|
+
);
|
|
297
309
|
|
|
298
|
-
const searchFlightsState = askPassengers.transitionTo(
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
310
|
+
const searchFlightsState = askPassengers.transitionTo(
|
|
311
|
+
{
|
|
312
|
+
toolState: searchFlights,
|
|
313
|
+
// Triggered when shouldSearchFlights flag is set by hook
|
|
314
|
+
},
|
|
315
|
+
"All basic info gathered, search for available flights"
|
|
316
|
+
);
|
|
302
317
|
|
|
303
|
-
const presentFlights = searchFlightsState.transitionTo(
|
|
304
|
-
|
|
305
|
-
|
|
318
|
+
const presentFlights = searchFlightsState.transitionTo(
|
|
319
|
+
{
|
|
320
|
+
chatState: "Present available flights and ask which one works for them",
|
|
321
|
+
},
|
|
322
|
+
"Flight search complete, present options to customer"
|
|
323
|
+
);
|
|
306
324
|
|
|
307
325
|
// Happy path: customer selects a flight
|
|
308
|
-
const confirmBooking = presentFlights.transitionTo(
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
326
|
+
const confirmBooking = presentFlights.transitionTo(
|
|
327
|
+
{
|
|
328
|
+
chatState: "Confirm booking details before proceeding",
|
|
329
|
+
gather: ["cabinClass", "urgency"], // Additional optional data
|
|
330
|
+
},
|
|
331
|
+
"Customer interested in a flight, confirm booking details"
|
|
332
|
+
);
|
|
312
333
|
|
|
313
|
-
const bookFlightState = confirmBooking.transitionTo(
|
|
314
|
-
|
|
315
|
-
|
|
334
|
+
const bookFlightState = confirmBooking.transitionTo(
|
|
335
|
+
{
|
|
336
|
+
toolState: bookFlight,
|
|
337
|
+
},
|
|
338
|
+
"Customer confirmed, proceed with booking"
|
|
339
|
+
);
|
|
316
340
|
|
|
317
|
-
const provideConfirmation = bookFlightState.transitionTo(
|
|
318
|
-
|
|
319
|
-
|
|
341
|
+
const provideConfirmation = bookFlightState.transitionTo(
|
|
342
|
+
{
|
|
343
|
+
chatState: "Provide confirmation number and booking summary",
|
|
344
|
+
},
|
|
345
|
+
"Booking completed successfully"
|
|
346
|
+
);
|
|
320
347
|
|
|
321
|
-
provideConfirmation.transitionTo(
|
|
348
|
+
provideConfirmation.transitionTo(
|
|
349
|
+
{ state: END_ROUTE },
|
|
350
|
+
"Customer has confirmation, booking flow complete"
|
|
351
|
+
);
|
|
322
352
|
|
|
323
353
|
// Add route-specific guidelines
|
|
324
354
|
flightBookingRoute.createGuideline({
|
|
@@ -356,22 +386,34 @@ async function createTravelAgent() {
|
|
|
356
386
|
},
|
|
357
387
|
});
|
|
358
388
|
|
|
359
|
-
const askConfirmation = bookingStatusRoute.initialState.transitionTo(
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
389
|
+
const askConfirmation = bookingStatusRoute.initialState.transitionTo(
|
|
390
|
+
{
|
|
391
|
+
chatState: "Ask for the confirmation number or booking reference",
|
|
392
|
+
gather: ["confirmationNumber"],
|
|
393
|
+
skipIf: (extracted) => !!extracted.confirmationNumber,
|
|
394
|
+
},
|
|
395
|
+
"Customer wants to check booking status but hasn't provided confirmation number"
|
|
396
|
+
);
|
|
364
397
|
|
|
365
|
-
const checkStatus = askConfirmation.transitionTo(
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
398
|
+
const checkStatus = askConfirmation.transitionTo(
|
|
399
|
+
{
|
|
400
|
+
toolState: getBookingStatus,
|
|
401
|
+
requiredData: ["confirmationNumber"],
|
|
402
|
+
},
|
|
403
|
+
"Confirmation number provided, look up booking details"
|
|
404
|
+
);
|
|
369
405
|
|
|
370
|
-
const provideStatus = checkStatus.transitionTo(
|
|
371
|
-
|
|
372
|
-
|
|
406
|
+
const provideStatus = checkStatus.transitionTo(
|
|
407
|
+
{
|
|
408
|
+
chatState: "Provide booking status and relevant information",
|
|
409
|
+
},
|
|
410
|
+
"Booking status retrieved successfully"
|
|
411
|
+
);
|
|
373
412
|
|
|
374
|
-
provideStatus.transitionTo(
|
|
413
|
+
provideStatus.transitionTo(
|
|
414
|
+
{ state: END_ROUTE },
|
|
415
|
+
"Booking information provided to customer"
|
|
416
|
+
);
|
|
375
417
|
|
|
376
418
|
// Global guidelines
|
|
377
419
|
agent.createGuideline({
|