问题
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);
}
}
回答1:
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.
来源:https://stackoverflow.com/questions/56372747/how-can-i-control-the-microsoft-bot-framework-dialog-to-repeat-the-dialog-sequen