private async Task <OnTurnProperty> DetectIntentAndEntitiesAsync(ITurnContext turnContext) { // Handle card input (if any), update state and return. if (turnContext.Activity.Value != null) { if (turnContext.Activity.Value is JObject) { return(OnTurnProperty.FromCardInput((JObject)turnContext.Activity.Value)); } } // Acknowledge attachments from user. if (turnContext.Activity.Attachments != null && turnContext.Activity.Attachments.Count > 0) { await turnContext.SendActivityAsync("Thanks for sending me that attachment. I'm still learning to process attachments."); return(null); } // Nothing to do for this turn if there is no text specified. if (string.IsNullOrWhiteSpace(turnContext.Activity.Text) || string.IsNullOrWhiteSpace(turnContext.Activity.Text.Trim())) { return(null); } // Call to LUIS recognizer to get intent + entities. var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(turnContext, default(CancellationToken)); // Return new instance of on turn property from LUIS results. // Leverages static fromLUISResults method. return(OnTurnProperty.FromLuisResults(luisResults)); }
public async override Task <DialogTurnResult> ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { var turnContext = dc.Context; var step = dc.ActiveDialog.State; // Get reservation property. var newReservation = await _reservationsAccessor.GetAsync(turnContext, () => new ReservationProperty()); // Get on turn property. This has any entities that mainDispatcher, // or Bot might have captured in its LUIS model. var onTurnProperties = await _onTurnAccessor.GetAsync(turnContext, () => new OnTurnProperty("None", new List <EntityProperty>())); // If on turn property has entities.. ReservationResult updateResult = null; if (onTurnProperties.Entities.Count > 0) { // ...update reservation property with on turn property results. updateResult = newReservation.UpdateProperties(onTurnProperties); } // See if updates to reservation resulted in errors, if so, report them to user. if (updateResult != null && updateResult.Status == ReservationStatus.Incomplete && updateResult.Outcome != null && updateResult.Outcome.Count > 0) { await _reservationsAccessor.SetAsync(turnContext, updateResult.NewReservation); // Return and do not continue if there is an error. await turnContext.SendActivityAsync(updateResult.Outcome[0].Message); return(await base.ContinueDialogAsync(dc)); } // Call LUIS and get results. var luisResults = await _botServices.LuisServices[LuisConfiguration].RecognizeAsync(turnContext, cancellationToken); var topLuisIntent = luisResults.GetTopScoringIntent(); var topIntent = topLuisIntent.intent; // If we don't have an intent match from LUIS, go with the intent available via // the on turn property (parent's LUIS model). if (luisResults.Intents.Count <= 0) { // Go with intent in onTurnProperty. topIntent = string.IsNullOrWhiteSpace(onTurnProperties.Intent) ? "None" : onTurnProperties.Intent; } // Update object with LUIS result. updateResult = newReservation.UpdateProperties(OnTurnProperty.FromLuisResults(luisResults)); // See if update reservation resulted in errors, if so, report them to user. if (updateResult != null && updateResult.Status == ReservationStatus.Incomplete && updateResult.Outcome != null && updateResult.Outcome.Count > 0) { // Set reservation property. await _reservationsAccessor.SetAsync(turnContext, updateResult.NewReservation); // Return and do not continue if there is an error. await turnContext.SendActivityAsync(updateResult.Outcome[0].Message); return(await base.ContinueDialogAsync(dc)); } // Did user ask for help or said cancel or continuing the conversation? switch (topIntent) { case ContinuePromptIntent: // User does not want to make any change. updateResult.NewReservation.NeedsChange = false; break; case NoChangeIntent: // User does not want to make any change. updateResult.NewReservation.NeedsChange = false; break; case HelpIntent: // Come back with contextual help. var helpReadOut = updateResult.NewReservation.HelpReadOut(); await turnContext.SendActivityAsync(helpReadOut); break; case CancelIntent: // Start confirmation prompt. var opts = new PromptOptions { Prompt = new Activity { Type = ActivityTypes.Message, Text = "Are you sure you want to cancel?", }, }; return(await dc.PromptAsync(ConfirmCancelPrompt, opts)); case InterruptionsIntent: default: // If we picked up new entity values, do not treat this as an interruption. if (onTurnProperties.Entities.Count != 0 || luisResults.Entities.Count > 1) { break; } // Handle interruption. var onTurnProperty = await _onTurnAccessor.GetAsync(dc.Context); return(await dc.BeginDialogAsync(InterruptionDispatcher, onTurnProperty)); } // Set reservation property based on OnTurn properties. await _reservationsAccessor.SetAsync(turnContext, updateResult.NewReservation); return(await base.ContinueDialogAsync(dc)); }