1

As the dialog from the bot conversation starts it seems to go on a path i.e. 1 2 3 4. I would like to at point 2 per se go back to path marker 1 and start the process over or even potentially go to marker 2 from 3 to re-address / answer marker 2 over again...

I have attempted to do this with an if statement ( == "Pittsburgh" ) that returns to the previous method but I notice through the bot emulator the dialog moves on regardless of me readdressing the previous method.

In short, I am asking how to traverse through the waterfalldialog and go back to any dialog point I choose based on outcomes of conversation with the bot and luis responses. Meaning, if I am stepping through from 1 - 5 and at 3 I need to start over how can I conform the waterfalldialog to specifically do this? The issue I am having is that even though I am calling the previous method i the dialog chain it doesn't officially start from that method called onwards. That is my concern specifically.

       private async Task<DialogTurnResult> DestinationStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var bookingDetails = (BookingDetails)stepContext.Options;

            if (bookingDetails.Destination == null)
            {
                return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Where would you like to travel to Christian?") }, cancellationToken);
            }
            else
            {
                Console.WriteLine("testing christian" + bookingDetails);
                return await stepContext.NextAsync(bookingDetails.Destination, cancellationToken);
            }
        }

        private async Task<DialogTurnResult> OriginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            Console.WriteLine("testing paul");
            var bookingDetails = (BookingDetails)stepContext.Options;

            //await LuisHelper.ExecuteLuisQuery(Configuration, Logger, stepContext.Context, cancellationToken);

            if ((string)stepContext.Result == "Pittsburgh")
            {
               return await DestinationStepAsync(stepContext, cancellationToken);
            }

            bookingDetails.Destination = (string)stepContext.Result;

            if (bookingDetails.Origin == null)
            {
                Console.WriteLine("testing tall" + bookingDetails.Destination);
                return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Where are you traveling from?") }, cancellationToken);
            }
            else
            {
                return await stepContext.NextAsync(bookingDetails.Origin, cancellationToken);
            }
        }
Christian Matthew
  • 4,014
  • 4
  • 33
  • 43
  • You might be able to use the [ReplaceDialogAsync](https://learn.microsoft.com/en-us/dotnet/api/microsoft.bot.builder.dialogs.dialogcontext.replacedialogasync?view=botbuilder-dotnet-stable#Microsoft_Bot_Builder_Dialogs_DialogContext_ReplaceDialogAsync_System_String_System_Object_System_Threading_CancellationToken_) method to achieve your intended behaviour. – Matt Stannett May 30 '19 at 10:05
  • 1
    `WaterfallDialog` is designed to run step by step. Why not use a `ComponentDialog`? – itminus May 30 '19 at 10:06
  • @itminus I don't mind the step by step i will need to override it at some points. – Christian Matthew May 30 '19 at 14:31
  • @MattStannett i will look into that. What will this achieve exactly? will it be a replacement of waterfalldialog or in coordination with? – Christian Matthew May 30 '19 at 14:32
  • Possible duplicate of [Sequential Waterfall Models with Complex Dialog flows Bot Framework C# v4](https://stackoverflow.com/questions/53361886/sequential-waterfall-models-with-complex-dialog-flows-bot-framework-c-sharp-v4) – JJ_Wailes May 30 '19 at 15:46
  • @JJ_Wailes I have read through the qna from the question you posted. That is a tremendously helpful response to his question. However, I think my question is a little more basic as interaction with using the waterfalldialog interface. – Christian Matthew May 30 '19 at 17:02
  • 1
    Like @itminus said, waterfalls are designed to go A-> B-> C. If you want to be able to traverse sideways or slantways, you'll need to use ComponentDialogs. There's also this: https://stackoverflow.com/questions/52554441/bot-framework-v4-0-how-to-execute-the-previous-waterfall-step-in-a-dialog/52863951#52863951 – JJ_Wailes May 30 '19 at 17:29
  • 1
    You'll note in that second one, I use ReplaceDialogAsync to basically step back to a certain level in the waterfall. – JJ_Wailes May 30 '19 at 17:30
  • @JJ_Wailes I think that 2nd so qna is what I am looking for. However, you mention ComponentDialogs. Is that newer, better, different in what ways exactly? That response you give for the SO seems like a good pattern. – Christian Matthew May 30 '19 at 18:10
  • 2
    Just leaving this here as it doesn’t look like it’s been mentioned yet: https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-dialog-manage-complex-conversation-flow?view=azure-bot-service-4.0. – Matt Stannett May 30 '19 at 19:07
  • @MattStannett lol i mean that one is hot off the presses. I will look into this tonight. – Christian Matthew May 30 '19 at 21:36
  • @ChristianMatthew you can set the next waterfall step to execute before the end of the turn: stepContext.ActiveDialog.State["stepIndex"] = 2 Have you tried this? – Eric Dahlvang Jun 07 '19 at 16:19
  • @EricDahlvang I am doing a deep dive through all of the tutorials now. I think the issue here in a way and in short is about validation of a question and a response. I think this is at the heart of what people are asking when they use a dialog library and want to go back and or stop the flow the the dialog. What if I dont' like or want the users answer how do I go back and or reset. I am going to look over some more code and try to refactor the question to gain a good answer. – Christian Matthew Jun 09 '19 at 00:25

1 Answers1

0

To tuck this into an answer and get it out of comments:

Waterfalls are not designed to be traversed in anyway but step-by-step/down. You can either nest mini waterfalls inside each waterfall step which would allow for looping individual steps shown here or having conditional checks to skip certain steps shown here.

What you seem to be looking for is ComponentDialogs or using ReplaceDialogAsync. Component Dialogs, part of the botbuilder-dialogs library let you break your bot's logic into components (pieces) that can be added into either a DialogSet or even another component dialog. For example, this is the Cancel/Help component of the Core-Bot sample on the bot framework samples github repo. This component is for what happens if in the middle of another waterfall, the user says 'cancel' or 'help'

public class CancelAndHelpDialog : ComponentDialog
    {
        public CancelAndHelpDialog(string id)
            : base(id)
        {
        }

        protected override async Task<DialogTurnResult> OnBeginDialogAsync(DialogContext innerDc, object options, CancellationToken cancellationToken)
        {
            var result = await InterruptAsync(innerDc, cancellationToken);
            if (result != null)
            {
                return result;
            }

            return await base.OnBeginDialogAsync(innerDc, options, cancellationToken);
        }

        protected override async Task<DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken)
        {
            var result = await InterruptAsync(innerDc, cancellationToken);
            if (result != null)
            {
                return result;
            }

            return await base.OnContinueDialogAsync(innerDc, cancellationToken);
        }

        private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken)
        {
            if (innerDc.Context.Activity.Type == ActivityTypes.Message)
            {
                var text = innerDc.Context.Activity.Text.ToLowerInvariant();

                switch (text)
                {
                    case "help":
                    case "?":
                        await innerDc.Context.SendActivityAsync($"Show Help...");
                        return new DialogTurnResult(DialogTurnStatus.Waiting);

                    case "cancel":
                    case "quit":
                        await innerDc.Context.SendActivityAsync($"Cancelling");
                        return await innerDc.CancelAllDialogsAsync();
                }
            }

            return null;
        }
    }

As @Matt-Stannett mentioned: there is a tutorial as of 5/22/19 here on how to make complex dialogs including component dialogs.

JJ_Wailes
  • 2,207
  • 1
  • 9
  • 17
  • question... Is the first example you link to the same as using ComponentDialogs? – Christian Matthew May 31 '19 at 18:20
  • 1
    No, but it is a way to manipulate waterfalldialogs, mostly by creating a mini-waterfall in each step so you can confirm as you go. Waterfall dialogs were meant to mimic what used to be FormFlow from v3, but there was no way to "change your mind" if you will. It's just another way to add complexity to waterfalls. – JJ_Wailes May 31 '19 at 18:26
  • ok so what makes componentDialogs different and or better? Or for what I am asking is the complex waterfalls the best solution? I know I have to do it in order to confirm my own opinion but want to see what your thoughts are first. – Christian Matthew May 31 '19 at 20:00
  • "best solution" is really dependent on what the overarching purpose and hierarchy of your bot. Designing bots isn't really my strength, helping debug them is. – JJ_Wailes May 31 '19 at 21:48
  • JJ thank you for all the help... It may not be your strength but you are the only one that is helping so that is a great strength that is appreciated. After studying this response and other SO questions you have answered there is honestly more confusion. The good news is when reading your mini waterfall methodology it is clearish enough to understand the benefit. However, when considering component dialogs and their usage and interactions this is when the documentation and understanding falls apart completely. Can you help with a specific tutorial? I think that would clear up many things – Christian Matthew Jun 05 '19 at 15:04
  • one quick question is the tutorial listed by this answer... is that a miniwaterfall methodology and or component dialog? I dont' see it is either? – Christian Matthew Jun 05 '19 at 15:08
  • If you feel my answer was sufficient, please "accept" it so I can clear this ticket from my support tracker. Also, that tutorial covers BOTH waterfalls and component dialogs. – JJ_Wailes Jun 06 '19 at 15:48
  • JJ can you do one thing as I have studied this answer and feel it could be more informative based on what you have already provided. I can alter the title of my question too to make it more relevant if need be. Can you add this additional information to your answer as I am still unclear... How does the component dialog interact with the waterfall dialog. I see how they interact in the example but it seems to be the base way a dialog is setup i.e. the quarterback of the dialog and then the waterfall is the dialog operations of a 1 2 3 step based answer response system. would you agree? – Christian Matthew Jun 06 '19 at 20:40
  • 1
    This is a great answer and I have worked through it. I am going to edit to add a couple things and mark it as the correct answer thank you – Christian Matthew Jul 02 '19 at 17:10