/// <summary> /// Every conversation turn calls this method. /// </summary> /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed /// for processing this conversation turn. </param> /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns> /// <seealso cref="BotStateSet"/> /// <seealso cref="ConversationState"/> public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { if (turnContext == null) { throw new ArgumentException(nameof(turnContext)); } // Handle Message activity type, which is the main activity type for shown within a conversational interface // Message activities may contain text, speech, interactive cards, and binary or unknown attachments. // see https://aka.ms/about-bot-activity-message to learn more about the message and other activity types if (turnContext.Activity.Type == ActivityTypes.Message) { DialogContext dialogContext = await _dialogSet.CreateContextAsync(turnContext, cancellationToken); DialogTurnResult results = await dialogContext.ContinueDialogAsync(cancellationToken); switch (results.Status) { case DialogTurnStatus.Cancelled: case DialogTurnStatus.Empty: // If there is no active dialog, we should clear the user info and start a new dialog. await _botAccessor.UserProfileAccessor.SetAsync(turnContext, new IcMProfile(), cancellationToken); await _botAccessor.UserState.SaveChangesAsync(turnContext, false, cancellationToken); await dialogContext.BeginDialogAsync(TopLevelDialog, null, cancellationToken); break; case DialogTurnStatus.Complete: // If we just finished the dialog, capture and display the results. IcMProfile icMInfo = results.Result as IcMProfile; string status = "Thanks for the chat"; await turnContext.SendActivityAsync(status); await _botAccessor.UserProfileAccessor.SetAsync(turnContext, icMInfo, cancellationToken); await _botAccessor.UserState.SaveChangesAsync(turnContext, false, cancellationToken); break; case DialogTurnStatus.Waiting: // If there is an active dialog, we don't need to do anything here. break; } await _botAccessor.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken); // Echo back to the user whatever they typed. //await turnContext.SendActivityAsync("Hello World", cancellationToken: cancellationToken); } if (turnContext.Activity.Type == ActivityTypes.ConversationUpdate) { await turnContext.SendActivityAsync("Welcome to Online Support Engineer Bots", cancellationToken : cancellationToken); } }
protected override async Task CompleteAsync(DialogContext dc, DialogTurnResult result = null, CancellationToken cancellationToken = default(CancellationToken)) { var response = dc.Context.Activity.CreateReply(); response.Type = ActivityTypes.EndOfConversation; await dc.Context.SendActivityAsync(response); await dc.EndDialogAsync(result); }
protected override async Task CompleteAsync(DialogContext dc, DialogTurnResult result = null, CancellationToken cancellationToken = default(CancellationToken)) { // The active dialog's stack ended with a complete status await _responder.ReplyWith(dc.Context, MainResponses.ResponseIds.Completed); // Request feedback on the last activity. if (Id != nameof(OnboardingDialog)) { await FeedbackMiddleware.RequestFeedbackAsync(dc.Context, Id); } }
// Runs on every turn of the conversation to check if the conversation should be interrupted. protected async Task <DialogTurnResult> InterruptDialogAsync(DialogContext innerDc, CancellationToken cancellationToken) { DialogTurnResult interrupted = null; var activity = innerDc.Context.Activity; if (activity.Type == ActivityTypes.Message && !string.IsNullOrEmpty(activity.Text)) { } return(interrupted); }
private async Task <DialogTurnResult> entityPrompt( WaterfallStepContext step, CancellationToken cancellationToken = default(CancellationToken)) { DialogTurnResult returnResult = new DialogTurnResult(0); if (step.Options == null) { FoundChoice module = (FoundChoice)step.Result; ((BotUserEntityContext)step.Values[DialogKey]).module = module.Value; List <string> entities = _navigationEntityData.NavigationEntitiesForModule(module.Value.ToString()); returnResult = await step.PromptAsync( ChoicesPromptId, new PromptOptions { Prompt = MessageFactory.Text($"The {module.Value} area has the following topics that I know about. Please choose one that I can help with."), RetryPrompt = MessageFactory.Text("Please choose an option from the list."), Choices = ChoiceFactory.ToChoices(entities), }, cancellationToken); } else { FoundChoice branchChoice = (FoundChoice)step.Result; if (branchChoice.Value == "Choose an area") { ((BotUserEntityContext)step.Values[DialogKey]).module = branchChoice.Value; returnResult = await step.EndDialogAsync( (BotUserEntityContext)step.Values[DialogKey], cancellationToken); } else { ((BotUserEntityContext)step.Values[DialogKey]).module = ((BotUserEntityContext)step.Values[DialogKeyOptions]).module; ((BotUserEntityContext)step.Values[DialogKey]).entity = branchChoice.Value; List <string> entityIntents = _navigationEntityData.CrudActionForEntities(branchChoice.Value.ToString()); entityIntents.Add("Find"); returnResult = await step.PromptAsync( ChoicesPromptId, new PromptOptions { Prompt = MessageFactory.Text($"With the {branchChoice.Value} I can do the following things.Please select one."), RetryPrompt = MessageFactory.Text("Please choose an option from the list."), Choices = ChoiceFactory.ToChoices(entityIntents), }, cancellationToken); } } return(returnResult); }
protected override async Task CompleteAsync(DialogContext dc, DialogTurnResult result = null, CancellationToken cancellationToken = default(CancellationToken)) { // workaround. if connect skill directly to teams, the following response does not work. if (dc.Context.Adapter is IRemoteUserTokenProvider remoteInvocationAdapter || Channel.GetChannelId(dc.Context) != Channels.Msteams) { var response = dc.Context.Activity.CreateReply(); response.Type = ActivityTypes.EndOfConversation; await dc.Context.SendActivityAsync(response); } await dc.EndDialogAsync(result); }
// Runs on every turn of the conversation to check if the conversation should be interrupted. protected async Task <DialogTurnResult> InterruptDialogAsync(DialogContext innerDc, CancellationToken cancellationToken) { DialogTurnResult interrupted = null; var activity = innerDc.Context.Activity; if (activity.Type == ActivityTypes.Message && !string.IsNullOrEmpty(activity.Text)) { // Get connected LUIS result from turn state. var generalResult = innerDc.Context.TurnState.Get <General>(StateProperties.GeneralLuisResult); (var generalIntent, var generalScore) = generalResult.TopIntent(); if (generalScore > 0.5) { switch (generalIntent) { case General.Intent.Cancel: { var state = await _conversationStateAccessor.GetAsync(innerDc.Context, () => new RestaurantBookingState(), cancellationToken); state.Clear(); await innerDc.Context.SendActivityAsync(_localeTemplateManager.GenerateActivity(RestaurantBookingSharedResponses.CancellingMessage), cancellationToken); await innerDc.CancelAllDialogsAsync(cancellationToken); if (innerDc.Context.IsSkill()) { interrupted = await innerDc.EndDialogAsync(state.IsAction?new ActionResult { ActionSuccess = false } : null, cancellationToken); } else { interrupted = await innerDc.BeginDialogAsync(InitialDialogId, cancellationToken : cancellationToken); } break; } case General.Intent.Help: { await innerDc.Context.SendActivityAsync(_localeTemplateManager.GenerateActivity(RestaurantBookingMainResponses.HelpMessage), cancellationToken); await innerDc.RepromptDialogAsync(cancellationToken); interrupted = EndOfTurn; break; } } } } return(interrupted); }
// Runs on every turn of the conversation to check if the conversation should be interrupted. protected async Task <DialogTurnResult> InterruptDialogAsync(DialogContext innerDc, CancellationToken cancellationToken) { DialogTurnResult interrupted = null; var activity = innerDc.Context.Activity; if (activity.Type == ActivityTypes.Message && !string.IsNullOrEmpty(activity.Text)) { // Get connected LUIS result from turn state. var generalResult = innerDc.Context.TurnState.Get <General>(StateProperties.GeneralLuisResult); (var generalIntent, var generalScore) = generalResult.TopIntent(); if (generalScore > 0.5) { switch (generalIntent) { case General.Intent.Cancel: { await innerDc.Context.SendActivityAsync(_templateManager.GenerateActivityForLocale(MainStrings.CANCELLED), cancellationToken); await innerDc.CancelAllDialogsAsync(cancellationToken); if (innerDc.Context.IsSkill()) { var state = await _stateAccessor.GetAsync(innerDc.Context, () => new NewsSkillState(), cancellationToken : cancellationToken); interrupted = await innerDc.EndDialogAsync(state.IsAction?new ActionResult(false) : null, cancellationToken : cancellationToken); } else { interrupted = await innerDc.BeginDialogAsync(InitialDialogId, cancellationToken : cancellationToken); } break; } case General.Intent.Help: { await innerDc.Context.SendActivityAsync(HeroCardResponses.SendHelpCard(innerDc.Context, _templateManager), cancellationToken); await innerDc.RepromptDialogAsync(cancellationToken); interrupted = EndOfTurn; break; } } } } return(interrupted); }
protected override async Task RouteAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { // get current activity locale var locale = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; var localeConfig = _services.CognitiveModelSets[locale]; // Populate state from SkillContext slots as required await PopulateStateFromSkillContext(dc.Context); // Get skill LUIS model from configuration localeConfig.LuisServices.TryGetValue("BingSearchSkill", out var luisService); if (luisService == null) { throw new Exception("The specified LUIS Model could not be found in your Bot Services configuration."); } else { var turnResult = EndOfTurn; var result = await luisService.RecognizeAsync <BingSearchSkillLuis>(dc.Context, CancellationToken.None); var intent = result?.TopIntent().intent; switch (intent) { case BingSearchSkillLuis.Intent.GetCelebrityInfo: case BingSearchSkillLuis.Intent.SearchMovieInfo: case BingSearchSkillLuis.Intent.None: { turnResult = await dc.BeginDialogAsync(nameof(SearchDialog)); break; } default: { // intent was identified but not yet implemented await dc.Context.SendActivityAsync(_responseManager.GetResponse(MainResponses.FeatureNotAvailable)); turnResult = new DialogTurnResult(DialogTurnStatus.Complete); break; } } if (turnResult != EndOfTurn) { await CompleteAsync(dc); } } }
public static async Task Run(this Dialog dialog, ITurnContext turnContext, IStatePropertyAccessor <DialogState> dialogAccessor, CancellationToken cancellationToken = default(CancellationToken)) { DialogSet dialogSet = new DialogSet(dialogAccessor); dialogSet.Add(dialog); DialogContext dialogContext = await dialogSet.CreateContextAsync(turnContext, cancellationToken); DialogTurnResult results = await dialogContext.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { await dialogContext.BeginDialogAsync(dialog.Id, null, cancellationToken); } }
protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken) { DialogSet dialogSet = new DialogSet(_conversationState.CreateProperty <DialogState>("HeroState")); dialogSet.Add(_dialog); DialogContext dialogContext = await dialogSet.CreateContextAsync(turnContext, cancellationToken); DialogTurnResult results = await dialogContext.ContinueDialogAsync(cancellationToken); if (results.Status == DialogTurnStatus.Empty) { await dialogContext.BeginDialogAsync(_dialog.Id, null, cancellationToken); } }
protected TestFlow CreateTestFlow(string dialogName, bool userConsentGiven = true) { return(new TestFlow(this.adapter, async(turnContext, cancellationToken) => { this.turnContext = turnContext; this.cancellationToken = cancellationToken; if (turnContext.Activity.Type == ActivityTypes.Message) { // Initialize the dialog context. DialogContext dialogContext = await this.dialogs.CreateContextAsync(turnContext, cancellationToken); // Make sure this channel is supported. if (!Phrases.ValidChannels.Contains(turnContext.Activity.ChannelId)) { await Messages.SendAsync(Phrases.Greeting.InvalidChannel(turnContext), turnContext, cancellationToken); return; } // Create the master dialog. var masterDialog = new MasterDialog(this.state, this.dialogs, this.Api, this.Configuration); // If the user sends the update keyword, clear the dialog stack and start a new update. if (string.Equals(turnContext.Activity.Text, Phrases.Keywords.Update, StringComparison.OrdinalIgnoreCase)) { dialogName = MasterDialog.Name; await dialogContext.CancelAllDialogsAsync(cancellationToken); } // Attempt to continue any existing conversation. DialogTurnResult result = await masterDialog.ContinueDialogAsync(dialogContext, cancellationToken); // Start a new conversation if there isn't one already. if (result.Status == DialogTurnStatus.Empty) { // Clear the user context when a new conversation begins. await this.state.ClearUserContext(dialogContext.Context, cancellationToken); // Tests must init the user once there is a turn context. await InitUser(userConsentGiven); // Difference for tests here is beginning the given dialog instead of master so that individual dialog flows can be tested. await masterDialog.BeginDialogAsync(dialogContext, dialogName, null, cancellationToken); } } })); }
protected override async Task CompleteAsync(DialogContext dc, DialogTurnResult result = null, CancellationToken cancellationToken = default(CancellationToken)) { if (_skillMode) { var response = dc.Context.Activity.CreateReply(); response.Type = ActivityTypes.EndOfConversation; await dc.Context.SendActivityAsync(response); } else { await dc.Context.SendActivityAsync(dc.Context.Activity.CreateReply(EmailSharedResponses.ActionEnded)); } // End active dialog await dc.EndDialogAsync(result); }
/// <summary> /// Complete the conversation. /// </summary> /// <param name="dc">Current dialog context.</param> /// <param name="result">Result returned when dialog completed.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Completed Task.</returns> protected override async Task CompleteAsync(DialogContext dc, DialogTurnResult result = null, CancellationToken cancellationToken = default(CancellationToken)) { if (result?.Result != null && result.Result.ToString() == "StartNew") { await this.RouteAsync(dc); } else { var response = dc.Context.Activity.CreateReply(); response.Type = ActivityTypes.EndOfConversation; await dc.Context.SendActivityAsync(response); // End active dialog await dc.EndDialogAsync(result); } }
/// <summary> /// Forward an inbound activity on to the Skill. This is a synchronous operation whereby all response activities are aggregated and returned in one batch. /// </summary> /// <param name="innerDc">Inner DialogContext.</param> /// <param name="activity">Activity.</param> /// <returns>DialogTurnResult.</returns> private async Task <DialogTurnResult> ForwardToSkillAsync(DialogContext innerDc, Activity activity) { try { var handoffActivity = await _skillTransport.ForwardToSkillAsync(_skillManifest, _serviceClientCredentials, innerDc.Context, activity, GetTokenRequestCallback(innerDc)).ConfigureAwait(false); if (handoffActivity != null) { await innerDc.Context.SendActivityAsync(new Activity(type : ActivityTypes.Trace, text : $"<--Ending the skill conversation with the {_skillManifest.Name} Skill and handing off to Parent Bot.")).ConfigureAwait(false); return(await innerDc.EndDialogAsync(handoffActivity.SemanticAction?.Entities).ConfigureAwait(false)); } else if (_authDialogCancelled) { // cancel remote skill dialog if AuthDialog is cancelled await _skillTransport.CancelRemoteDialogsAsync(_skillManifest, _serviceClientCredentials, innerDc.Context).ConfigureAwait(false); await innerDc.Context.SendActivityAsync(new Activity(type : ActivityTypes.Trace, text : $"<--Ending the skill conversation with the {_skillManifest.Name} Skill and handing off to Parent Bot due to unable to obtain token for user.")).ConfigureAwait(false); return(await innerDc.EndDialogAsync().ConfigureAwait(false)); } else { var dialogResult = new DialogTurnResult(DialogTurnStatus.Waiting); // if there's any response we need to send to the skill queued // forward to skill and start a new turn while (_queuedResponses.Count > 0) { var lastEvent = _queuedResponses.Dequeue(); dialogResult = await ForwardToSkillAsync(innerDc, lastEvent).ConfigureAwait(false); } return(dialogResult); } } catch { // Something went wrong forwarding to the skill, so end dialog cleanly and throw so the error is logged. // NOTE: errors within the skill itself are handled by the OnTurnError handler on the adapter. await innerDc.EndDialogAsync().ConfigureAwait(false); throw; } }
private async Task <DialogTurnResult> entityIntentPrompt( WaterfallStepContext step, CancellationToken cancellationToken = default(CancellationToken)) { DialogTurnResult returnResult = new DialogTurnResult(0); if (step.Options == null) { FoundChoice entity = (FoundChoice)step.Result; ((BotUserEntityContext)step.Values[DialogKey]).entity = entity.Value; //Custom Code Start | Removed Block //List<string> entityIntents = _navigationEntityData.CrudActionForEntities(entity.Value.ToString()); //entityIntents.Add("Find"); //returnResult = await step.PromptAsync( // ChoicesPromptId, // new PromptOptions // { // Prompt = MessageFactory.Text($"With the {entity.Value} I can do the following things.Please select one."), // RetryPrompt = MessageFactory.Text("Please choose an option from the list."), // Choices = ChoiceFactory.ToChoices(entityIntents), // }, // cancellationToken); //Custom Code End //Custom Code Start | Added Code Block ((BotUserEntityContext)step.Values[DialogKey]).entityIntent = "Create"; return(await step.EndDialogAsync( (BotUserEntityContext)step.Values[DialogKey], cancellationToken)); //Custom Code End } else { FoundChoice entityintent = (FoundChoice)step.Result; ((BotUserEntityContext)step.Values[DialogKey]).entityIntent = entityintent.Value; returnResult = await step.EndDialogAsync( (BotUserEntityContext)step.Values[DialogKey], cancellationToken); } return(returnResult); }
/// <summary> /// Every conversation turn for our Echo Bot will call this method. /// There are no dialogs used, since it's "single turn" processing, meaning a single /// request and response. /// </summary> /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed /// for processing this conversation turn. </param> /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns> /// <seealso cref="BotStateSet"/> /// <seealso cref="ConversationState"/> /// <seealso cref="IMiddleware"/> public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { if (turnContext.Activity.Type == ActivityTypes.Message) { DialogContext dc = await _dialogs.CreateContextAsync(turnContext, cancellationToken); // Get the state properties from the turn context. CustomerInfo userProfile = await _accessors.CustomerInfoAccessor.GetAsync(turnContext, () => new CustomerInfo()); // Continue any current dialog. DialogTurnResult dialogTurnResult = await dc.ContinueDialogAsync(); if (dialogTurnResult.Result is null) { // Get the intent recognition result var recognizerResult = await botServices.LuisServices["AMAAirlinesDispatch"].RecognizeAsync(turnContext, cancellationToken); var topIntent = recognizerResult?.GetTopScoringIntent(); if (topIntent == null) { await turnContext.SendActivityAsync("Unable to get the top intent."); } else { await DispatchToTopIntentAsync(turnContext, dc, topIntent, cancellationToken); } } } else if (turnContext.Activity.Type == ActivityTypes.ConversationUpdate) { // Send a welcome message to the user and tell them what actions they may perform to use this bot if (turnContext.Activity.MembersAdded != null) { await SendWelcomeMessageAsync(turnContext, cancellationToken); } } // Save the new turn count into the conversation state. await _accessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken); await _accessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken); }
protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken) { DialogContext dc = await Dialogs.CreateContextAsync(turnContext, cancellationToken); // Continue any current dialog. DialogTurnResult dialogTurnResult = await dc.ContinueDialogAsync(); if (dialogTurnResult.Result is null) { // First, we use the dispatch model to determine which cognitive service (LUIS or QnA) to use. var recognizerResult = await _botServices.FoodDispatch.RecognizeAsync(turnContext, cancellationToken); // Top intent tell us which cognitive service to use. var topIntent = recognizerResult.GetTopScoringIntent(); // Next, we call the dispatcher with the top intent. await DispatchToTopIntentAsync(turnContext, dc, topIntent.intent, recognizerResult, cancellationToken); } }
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default) { if (turnContext.Activity.Type == ActivityTypes.Message) { // Establish context for our dialog from the turn context. DialogContext dialogContext = await this.dialogs.CreateContextAsync(turnContext, cancellationToken); // Make sure this channel is supported. if (!Phrases.ValidChannels.Contains(turnContext.Activity.ChannelId)) { await Messages.SendAsync(Phrases.Greeting.InvalidChannel(turnContext), turnContext, cancellationToken); return; } var schemaError = Helpers.ValidateSchema(); if (!string.IsNullOrEmpty(schemaError)) { await Messages.SendAsync(Phrases.Greeting.InvalidSchema(schemaError), turnContext, cancellationToken); return; } // Create the master dialog. var masterDialog = new MasterDialog(this.state, this.dialogs, this.api, this.configuration); // If the user sends the update keyword, clear the dialog stack and start a new session. if (string.Equals(turnContext.Activity.Text, Phrases.Keywords.Update, StringComparison.OrdinalIgnoreCase)) { await dialogContext.CancelAllDialogsAsync(cancellationToken); } // Attempt to continue any existing conversation. DialogTurnResult result = await masterDialog.ContinueDialogAsync(dialogContext, cancellationToken); // Start a new conversation if there isn't one already. if (result.Status == DialogTurnStatus.Empty) { await masterDialog.BeginDialogAsync(dialogContext, MasterDialog.Name, null, cancellationToken); } } }
/// <summary> /// Every conversation turn calls this method. /// </summary> /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed /// for processing this conversation turn. </param> /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns> /// <seealso cref="BotStateSet"/> /// <seealso cref="ConversationState"/> public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { // Handle Message activity type, which is the main activity type for shown within a conversational interface // Message activities may contain text, speech, interactive cards, and binary or unknown attachments. // see https://aka.ms/about-bot-activity-message to learn more about the message and other activity types if (turnContext.Activity.Type == ActivityTypes.Message) { DialogContext dialogContext = await _dialogs.CreateContextAsync(turnContext, cancellationToken); DialogTurnResult results = await dialogContext.ContinueDialogAsync(cancellationToken); switch (results.Status) { case DialogTurnStatus.Cancelled: case DialogTurnStatus.Empty: await dialogContext.BeginDialogAsync(_dialogHelper.ActiveLearningDialogName, _qnaMakerOptions, cancellationToken); break; case DialogTurnStatus.Complete: break; case DialogTurnStatus.Waiting: // If there is an active dialog, we don't need to do anything here. break; } await _accessors.ConversationState.SaveChangesAsync(turnContext); } else if (turnContext.Activity.Type == ActivityTypes.ConversationUpdate) { if (turnContext.Activity.MembersAdded != null) { // Send a welcome message to the user and tell them what actions they may perform to use this bot await SendWelcomeMessageAsync(turnContext, cancellationToken); } } else { await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected", cancellationToken : cancellationToken); } }
public static async Task Run(this Dialog dialog, ITurnContext turnContext, IStatePropertyAccessor <DialogState> accessor, CancellationToken cancellationToken) { //Creo un dialog set a partir del accesor de state DialogSet dialogSet = new DialogSet(accessor); //Agrego el dialogo actual al set dialogSet.Add(dialog); //Creo un dialo context a parti del turn DialogContext dialogContext = await dialogSet.CreateContextAsync(turnContext, cancellationToken); //Obtengo el resultado de continuar con el dialogo actual DialogTurnResult result = await dialogContext.ContinueDialogAsync(cancellationToken); //Si no hay ningun dialogo corriendo, iniciamos el actual if (result.Status == DialogTurnStatus.Empty) { await dialogContext.BeginDialogAsync(dialog.Id, null, cancellationToken); } }
private async Task <DialogTurnResult> modulePrompt( WaterfallStepContext step, CancellationToken cancellationToken = default(CancellationToken)) { step.Values[DialogKey] = _botUserEntityContext; DialogTurnResult returnResult = new DialogTurnResult(0); if (step.Options == null) { List <string> modules = new List <string>(); _navigationEntityData.NavigationModules().ToList() .ForEach(k => modules.Add(k.ToString())); returnResult = await step.PromptAsync( ChoicesPromptId, new PromptOptions { Prompt = MessageFactory.Text("I know about the following areas. Please choose one that I can help with."), RetryPrompt = MessageFactory.Text("Please choose an option from the list."), Choices = ChoiceFactory.ToChoices(modules), }, cancellationToken); } else { step.Values[DialogKeyOptions] = (BotUserEntityContext)step.Options; List <string> branchOptions = _navigationEntityData.BranchEntitiesForEntity(((BotUserEntityContext)step.Options).entity); returnResult = await step.PromptAsync( ChoicesPromptId, new PromptOptions { Prompt = MessageFactory.Text("What would like to do next?."), RetryPrompt = MessageFactory.Text("Please choose an option from the list."), Choices = ChoiceFactory.ToChoices(branchOptions), }, cancellationToken); } return(returnResult); }
private bool ShouldEndDialog(DialogTurnResult turnResult, out DialogTurnResult finalTurnResult) { finalTurnResult = turnResult; // Insure BreakLoop ends the dialog if (finalTurnResult.Status == DialogTurnStatus.Complete && finalTurnResult.Result is ActionScopeResult asr && asr.ActionScopeCommand == ActionScopeCommands.BreakLoop) { return(true); } // If a descendant dialog multiple levels below this container ended stack processing, // the result will be nested. while (finalTurnResult.Result != null && finalTurnResult.Result is DialogTurnResult dtr && dtr.ParentEnded && dtr.Status == DialogTurnStatus.Complete) { finalTurnResult = dtr; } return(finalTurnResult.ParentEnded && finalTurnResult.Status == DialogTurnStatus.Complete); }
public async override Task <DialogTurnResult> ContinueDialogAsync(DialogContext outerDc, CancellationToken cancellationToken = default(CancellationToken)) { DialogTurnResult turnResult = null; try { turnResult = await base.ContinueDialogAsync(outerDc, cancellationToken); if (turnResult.Status == DialogTurnStatus.Complete) { await ResumeAfterHotelsFormDialog(outerDc, turnResult.Result as HotelsQuery); } } catch (FormCanceledException <HotelsQuery> ) { //user cancelled, ignore the exception await outerDc.Context.SendActivityAsync("Okay, cancelled."); turnResult = new DialogTurnResult(DialogTurnStatus.Cancelled); await outerDc.EndDialogAsync(cancellationToken); } return(turnResult); }
private async Task Complete(DialogTurnResult dialogResult, DialogContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } switch (dialogResult.Status) { case DialogTurnStatus.Waiting: // The active dialog is waiting for a response from the user, so do nothing. break; case DialogTurnStatus.Complete: await context.EndDialogAsync(); break; default: await context.CancelAllDialogsAsync(); break; } }
/// <summary> /// Every conversation turn calls this method. /// </summary> /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed /// for processing this conversation turn. </param> /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns> /// <seealso cref="BotStateSet"/> /// <seealso cref="ConversationState"/> public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { // Get the state properties from the turn context. ConversationData conversationData = await _accessors.ConversationDataAccessor.GetAsync(turnContext, () => new ConversationData()); // Get the user's info. UserInfo userInfo = await _accessors.UserInfoAccessor.GetAsync(turnContext, () => new UserInfo(), cancellationToken); _logger.LogInformation(turnContext.Activity.Type); // Establish dialog state from the conversation state. DialogContext dc = await _dialogs.CreateContextAsync(turnContext, cancellationToken); // Handle Message activity type, which is the main activity type for shown within a conversational interface // Message activities may contain text, speech, interactive cards, and binary or unknown attachments. // see https://aka.ms/about-bot-activity-message to learn more about the message and other activity types if (turnContext.Activity.Type == ActivityTypes.Message) { // Continue any current dialog. DialogTurnResult dialogTurnResult = await dc.ContinueDialogAsync(); // Process the result of any complete dialog. if (dialogTurnResult.Status is DialogTurnStatus.Complete) { switch (dialogTurnResult.Result) { case GuestInfo guestInfo: // Store the results of the greeting dialog. userInfo.Guest = guestInfo; await _accessors.UserInfoAccessor.SetAsync(turnContext, userInfo, cancellationToken); // Show the main menu dialog await dc.BeginDialogAsync(MainDialogId, null, cancellationToken); break; default: // We shouldn't get here, since the main dialog is designed to loop. break; } } // Every dialog step sends a response, so if no response was sent, // then no dialog is currently active. else if (!turnContext.Responded) { // Otherwise, start our bot's main dialog. await dc.BeginDialogAsync(MainDialogId, null, cancellationToken); } } // Greet when users are added to the conversation. // Note that all channels do not send the conversation update activity. // If you find that this bot works in the emulator, but does not in // another channel the reason is most likely that the channel does not // send this activity. else if (turnContext.Activity.Type == ActivityTypes.ConversationUpdate) { _logger.LogInformation("Welcome Message Area"); if (turnContext.Activity.MembersAdded != null) { // Iterate over all new members added to the conversation foreach (var member in turnContext.Activity.MembersAdded) { // Greet anyone that was not the target (recipient) of this message // the 'bot' is the recipient for events from the channel, // turnContext.Activity.MembersAdded == turnContext.Activity.Recipient.Id indicates the // bot was added to the conversation. if (member.Id != turnContext.Activity.Recipient.Id) { await turnContext.SendActivityAsync($"Hi there - {member.Name}. {WelcomeMessage}", cancellationToken : cancellationToken); //await turnContext.SendActivityAsync($"What's your name?", cancellationToken: cancellationToken); await dc.BeginDialogAsync(GreetingDialogId, null, cancellationToken); // Can't start a dialog from ConversationUpdated //await dc.BeginDialogAsync(MainDialogId, null, cancellationToken); } } } } // Save the new turn count into the conversation state. await _accessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken); await _accessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken); }
protected override async Task RouteAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { var state = await _toDoStateAccessor.GetAsync(dc.Context, () => new ToDoSkillState()); // get current activity locale var locale = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; var localeConfig = _services.CognitiveModelSets[locale]; // Initialize the PageSize and ReadSize parameters in state from configuration InitializeConfig(state); // If dispatch result is general luis model localeConfig.LuisServices.TryGetValue("todo", out var luisService); if (luisService == null) { throw new Exception("The specified LUIS Model could not be found in your Bot Services configuration."); } else { var turnResult = EndOfTurn; var intent = state.LuisResult?.TopIntent().intent; var generalTopIntent = state.GeneralLuisResult?.TopIntent().intent; // switch on general intents switch (intent) { case todoLuis.Intent.AddToDo: { turnResult = await dc.BeginDialogAsync(nameof(AddToDoItemDialog)); break; } case todoLuis.Intent.MarkToDo: { turnResult = await dc.BeginDialogAsync(nameof(MarkToDoItemDialog)); break; } case todoLuis.Intent.DeleteToDo: { turnResult = await dc.BeginDialogAsync(nameof(DeleteToDoItemDialog)); break; } case todoLuis.Intent.ShowNextPage: case todoLuis.Intent.ShowPreviousPage: case todoLuis.Intent.ShowToDo: { turnResult = await dc.BeginDialogAsync(nameof(ShowToDoItemDialog)); break; } case todoLuis.Intent.None: { if (generalTopIntent == General.Intent.ShowNext || generalTopIntent == General.Intent.ShowPrevious) { turnResult = await dc.BeginDialogAsync(nameof(ShowToDoItemDialog)); } else { // No intent was identified, send confused message await dc.Context.SendActivityAsync(_responseManager.GetResponse(ToDoMainResponses.DidntUnderstandMessage)); turnResult = new DialogTurnResult(DialogTurnStatus.Complete); } break; } default: { // intent was identified but not yet implemented await dc.Context.SendActivityAsync(_responseManager.GetResponse(ToDoMainResponses.FeatureNotAvailable)); turnResult = new DialogTurnResult(DialogTurnStatus.Complete); break; } } if (turnResult != EndOfTurn) { await CompleteAsync(dc); } } }
protected override async Task CompleteAsync(DialogContext dc, DialogTurnResult result = null, CancellationToken cancellationToken = default(CancellationToken)) { // The active dialog's stack ended with a complete status await _responder.ReplyWith(dc.Context, MainResponses.ResponseIds.Completed); }
/// <summary> /// Called when the inner dialog stack is complete. /// </summary> /// <param name="innerDc">The dialog context for the component.</param> /// <param name="result">The dialog result when inner dialog completed.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> protected virtual Task CompleteAsync(DialogContext innerDc, DialogTurnResult result = null, CancellationToken cancellationToken = default(CancellationToken)) { innerDc.EndDialogAsync(result).Wait(cancellationToken); return(Task.CompletedTask); }
// Every conversation turn for our Echo Bot will call this method. public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { if (turnContext == null) { throw new ArgumentNullException(nameof(turnContext)); } // Handle Message activity type, which is the main activity type for shown within a conversational interface if (turnContext.Activity.Type == ActivityTypes.Message) { // Establish dialog state from the conversation state. DialogContext dc = await _dialogs.CreateContextAsync(turnContext, cancellationToken); // Get the user's info. UserProfile userInfo = await _accessors.UserProfile.GetAsync(turnContext, () => new UserProfile(), cancellationToken); // ONGOING DIALOG CASE: Continue any current dialog. DialogTurnResult dialogTurnResult = await dc.ContinueDialogAsync(); // COMPLETED DIALOG CASE: last result was EndDialogAsync, process the result of any complete dialog if (dialogTurnResult.Status is DialogTurnStatus.Complete) { switch (dialogTurnResult.Result) { case UserProfile upResult: // Store the results of FFHelloDialog await _accessors.UserProfile.SetAsync(turnContext, upResult, cancellationToken); //await _accessors.UserProfile.SetAsync(turnContext, upResult); // now start our bot's main dialog. await dc.BeginDialogAsync(MainDialogId, null, cancellationToken); break; default: // We shouldn't get here, since the main dialog is designed to loop. break; } } // INACTIVE DIALOG CASE: Every dialog step sends a response, so if no response was sent, // then no dialog is currently active. else if (!turnContext.Responded) { if (string.IsNullOrEmpty(userInfo.UserName)) //string.IsNullOrEmpty(userInfo.Guest?.Name)) { // If we don't yet have the guest's info, start the check-in dialog. await dc.BeginDialogAsync(FFHelloDialogId, null, cancellationToken); } else { // Otherwise, start our bot's main dialog. await dc.BeginDialogAsync(MainDialogId, null, cancellationToken); } } // Save the new turn count into the conversation state. await _accessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken); await _accessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken); } else { await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected"); } }