@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.
@@ -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
- chatState: "Ask what the patient needs an appointment for",
166
- gather: ["appointmentReason"],
167
- skipIf: (extracted) => !!extracted.appointmentReason,
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
- chatState: "Check if this is urgent and show available slots",
173
- gather: ["urgency"],
174
- skipIf: (extracted) => !!extracted.urgency,
175
- requiredData: ["appointmentReason"],
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
- toolState: scheduleAppointment,
205
- requiredData: ["appointmentReason", "preferredTime", "preferredDate"],
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({ state: END_ROUTE });
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
- chatState: "Ask for business name and a brief description",
274
- gather: ["businessName", "businessDescription"],
275
- skipIf: (extracted) =>
276
- !!extracted.businessName && !!extracted.businessDescription,
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
- toolState: saveBusinessInfo,
282
- requiredData: ["businessName", "businessDescription"],
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({
@@ -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
- chatState: "Ask about the destination",
275
- gather: ["destination"],
276
- skipIf: (extracted) => !!extracted.destination,
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
- toolState: lookupDestinationCode,
281
- requiredData: ["destination"],
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
- chatState: "Ask about preferred travel dates",
286
- gather: ["departureDate"],
287
- skipIf: (extracted) => !!extracted.departureDate,
288
- requiredData: ["destination"],
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
- chatState: "Ask for number of passengers",
293
- gather: ["passengers"],
294
- skipIf: (extracted) => !!extracted.passengers,
295
- requiredData: ["destination", "departureDate"],
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
- toolState: searchFlights,
300
- // Triggered when shouldSearchFlights flag is set by hook
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
- chatState: "Present available flights and ask which one works for them",
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
- chatState: "Confirm booking details before proceeding",
310
- gather: ["cabinClass", "urgency"], // Additional optional data
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
- toolState: bookFlight,
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
- chatState: "Provide confirmation number and booking summary",
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({ state: END_ROUTE });
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
- chatState: "Ask for the confirmation number or booking reference",
361
- gather: ["confirmationNumber"],
362
- skipIf: (extracted) => !!extracted.confirmationNumber,
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
- toolState: getBookingStatus,
367
- requiredData: ["confirmationNumber"],
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
- chatState: "Provide booking status and relevant information",
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({ state: END_ROUTE });
413
+ provideStatus.transitionTo(
414
+ { state: END_ROUTE },
415
+ "Booking information provided to customer"
416
+ );
375
417
 
376
418
  // Global guidelines
377
419
  agent.createGuideline({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@falai/agent",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "Standalone, strongly-typed AI Agent framework with route DSL and AI provider strategy",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",