Waterfall dialog prompts not working in bot framework

1.3k Views Asked by At

I am still trying to grasp the concepts of bot framework v4 and dialogs. I am trying to create a simple bot which integrates with QnAMaker and LUIS. Both integrations work separately but I am not able to integrate them both. I am using ASP.NET Core for the first time as well. So my problem might be with that too.

So I have created a bot based on this sample.

I have a base dialog which inherits Dialog class. The base class exposes an abstract function which the child dialog class inherits. The child class is called RootDialog.

FunctionDialogBase:

    public FunctionDialogBase(string dialogId, IConfiguration configuration, ILogger logger) : base(dialogId)
    {
        Configuration = configuration;
        Logger = logger;
    }
    public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dialogContext, object options = null, CancellationToken cancellationToken = default(CancellationToken))
    {   
        return await RunStateMachineAsync(dialogContext, cancellationToken).ConfigureAwait(false);
    }
    public override async Task<DialogTurnResult> ContinueDialogAsync(DialogContext dialogContext, CancellationToken cancellationToken = default(CancellationToken))
    {
        return await RunStateMachineAsync(dialogContext, cancellationToken).ConfigureAwait(false);
    }

    //abstract method
    protected abstract Task<(object newState, IEnumerable<Activity> output, object result)> ProcessAsync(object oldState, 
        Activity activity,
        DialogContext dialogContext,
        SPEntityDetails spEntityDetails,
        CancellationToken cancellationToken);

    private async Task<DialogTurnResult> RunStateMachineAsync(DialogContext dialogContext, CancellationToken cancellationToken)
        {
            var (newState, output, result) = await ProcessAsync(oldState, dialogContext.Context.Activity, dialogContext, spEntityDetails, cancellationToken).ConfigureAwait(false);     
            //do some more logic here
        }
    }

The RootDialog calls another dialog called CreateSiteDialog from its abstract method implementation like this:

RootDialog:

    protected override async Task<(object newState, IEnumerable<Activity> output, object result)> ProcessAsync(
    object oldState, 
    Activity activity,
    DialogContext dialogContext,
    SPEntityDetails spEntityDetails, 
    CancellationToken cancellationToken)
    {
        dialogContext.Dialogs.Add(new CreateSiteDialog());
        await dialogContext.BeginDialogAsync(nameof(CreateSiteDialog),spEntityDetails, cancellationToken);
        return (null, new Activity[] { activity.CreateReply("Site created successfully.") }, null);
    }       

And finally the CreateSiteDialog which has the issue. This dialog follows a waterfall model and should in theory move from one waterfall step to the next until the end. This is not happening. When I use the prompt in the first step, it executes and comes out of the waterfall dialog. The next waterfall step is never executed.

CreateSiteDialog:

public class CreateSiteDialog : CancelAndHelpDialog
{
    public CreateSiteDialog() : base(nameof(CreateSiteDialog))
    {
        AddDialog(new TextPrompt(nameof(TextPrompt)));
        AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));
        AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
        {
            ConfirmStepAsync,
            FinalStepAsync
        }));

        // The initial child Dialog to run.
        InitialDialogId = nameof(WaterfallDialog);
    }

    private async Task<DialogTurnResult> ConfirmStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        var spEntityDetails = (SPEntityDetails)stepContext.Options;
        var msg = @"Creating site: http://yoursiteurl/"  + spEntityDetails.SiteName + ". Confirm Yes/No.";          
        return await stepContext.PromptAsync(nameof(ConfirmPrompt), new PromptOptions { Prompt = MessageFactory.Text(msg) }, cancellationToken);        
    }
    private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        //handle propmt result from user action
    }
}

There's no error as well. So I am assuming I am doing something wrong in the usage of the dialogs. Please. Any help will be appreciated.

I am using Visual Studio 2017, Bot Framework Emulator, Bot framework V4 with a Core Bot project.

1

There are 1 best solutions below

2
On

For the life of me, I can't get Waterfall Dialogs working with that sample as a base (without basically rewriting the whole thing). I recommend you base your bot off of a combination of 11.qnamaker and 13.core-bot (which uses LUIS and is a good example for ComponentDialogs). I make this recommendation for two reasons:

  1. The sample you linked is "experimental" meaning not only is it not ready for production, but it may never be.
  2. The sample you linked uses a State Machine design, which isn't--and hasn't been--used by any other bot samples, so it will be very difficult to get good support.

For getting QnAMaker and LUIS working together, the flow is really going to be based off of your use case. I can't tell from your included code what you're going for. So, this answer is mainly for getting Waterfall Dialogs to work.