当我第一次运行该应用程序时,我正在执行一些初始化步骤,例如询问姓名和通信模式(聊天或说话),我使用BeginDialogAsync来启动相应的提示对话框。但是,对提示做出响应后,它会返回到我创建的MainDialog.cs,以使用LUIS检查用户输入,而不是转到下一个瀑布步骤。
代码
OptionsDialog.cs
private void InitializeWaterfallDialog()
{
var waterfallSteps = new WaterfallStep[]
{
InitialStepAsync,
FinalStepAsync
};
AddDialog(new WaterfallDialog($"{nameof(OptionsDialog)}.mainFlow", waterfallSteps));
AddDialog(new ChoicePrompt($"{nameof(OptionsDialog)}.communicationMode"));
InitialDialogId = $"{nameof(OptionsDialog)}.mainFlow";
}
private async Task<DialogTurnResult> InitialStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
return await stepContext.PromptAsync($"{nameof(OptionsDialog)}.communicationMode",
new PromptOptions
{
Prompt = MessageFactory.Text("Please select how you want to continue interacting with me."),
Choices = ChoiceFactory.ToChoices(new List<string> { "Chat", "Speak" }),
}, cancellationToken);
}
private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var attachments = new List<Attachment>();
var reply = MessageFactory.Attachment(attachments);
switch (((FoundChoice)stepContext.Result).Value)
{
case "Chat":
reply.Text = "Type something to start";
break;
case "Speak":
reply.Text = "This option is yet to be configured. Continuing with chat option. Type something to start";
break;
}
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
return await stepContext.EndDialogAsync(null, cancellationToken);
}
}
MainDialog.cs
private void InitializeWaterfallDialog()
{
var waterfallSteps = new WaterfallStep[]
{
InitialStepAsync,
FinalStepAsync
};
AddDialog(new OptionsDialog($"{nameof(MainDialog)}.options", _botStateService));
AddDialog(new GreetingDialog($"{nameof(MainDialog)}.greeting", _botStateService));
AddDialog(new RevenueDialog($"{nameof(MainDialog)}.revenue", _botStateService, _botServices, _financialServices, _currencyService));
AddDialog(new QuarterlyRevenueDialog($"{nameof(MainDialog)}.quarterlyRevenue", _botStateService, _botServices, _financialServices, _currencyService));
AddDialog(new ProfitDialog($"{nameof(MainDialog)}.profit", _botStateService, _botServices, _financialServices, _currencyService));
AddDialog(new QuarterlyProfitDialog($"{nameof(MainDialog)}.quarterlyProfit", _botStateService, _botServices, _financialServices, _currencyService));
AddDialog(new StockPriceDialog($"{nameof(MainDialog)}.stockPrice", _botStateService, _botServices, _financialServices, _currencyService));
AddDialog(new PersonNameDialog($"{nameof(MainDialog)}.personName", _botStateService, _botServices));
AddDialog(new FarewellDialog($"{nameof(MainDialog)}.farewell", _botStateService, _botServices));
AddDialog(new WaterfallDialog($"{nameof(MainDialog)}.mainFlow", waterfallSteps));
InitialDialogId = $"{nameof(MainDialog)}.mainFlow";
}
private async Task<DialogTurnResult> InitialStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
try
{
UserProfile userProfile = await _botStateService.UserProfileAccessor.GetAsync(stepContext.Context, () => new UserProfile());
var recognizerResult = await _botServices.Dispatch.RecognizeAsync(stepContext.Context, cancellationToken);
// Top intent tell us which cognitive service to use.
var topIntent = recognizerResult?.GetTopScoringIntent();
if(userProfile.HasRestartedConversation)
{
userProfile.HasRestartedConversation = false;
return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.options", null, cancellationToken);
}
else
{
switch (topIntent?.intent)
{
case "GreetingIntent":
return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.greeting", null, cancellationToken);
case "FindRevenueIntent":
return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.revenue", null, cancellationToken);
case "FindQuarterlyRevenueIntent":
return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.quarterlyRevenue", null, cancellationToken);
case "FindProfitIntent":
return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.profit", null, cancellationToken);
case "FindQuarterlyProfitIntent":
return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.quarterlyProfit", null, cancellationToken);
case "FindStockPriceIntent":
return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.stockPrice", null, cancellationToken);
case "FindPersonNameIntent":
return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.personName", null, cancellationToken);
case "FarewellIntent":
return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.farewell", null, cancellationToken);
case "CommunicationSelectIntent":
return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.options", null, cancellationToken);
case null:
break;
default:
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Sorry, I don’t have an answer for that. " +
$"(Please try something like 'What is revenue of google?')"), cancellationToken);
break;
}
}
await _botStateService.UserProfileAccessor.SetAsync(stepContext.Context, userProfile);
}
catch (Exception e)
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Sorry, there was an error sending your message. Please try again."), cancellationToken);
}
return await stepContext.NextAsync(null, cancellationToken);
}
在OptionsDialog中的InitialStepAsync中对提示做出响应后,它应该进入下一个瀑布步骤,即FinalStepAsync,但它将转到MainDialog并使用LUIS检查响应。
主要bot程序DialogBot.cs中的活动触发代码:
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
await base.OnTurnAsync(turnContext, cancellationToken);
// Save any state changes that might have occured during the turn.
await _botStateService.UserState.SaveChangesAsync(turnContext, false, cancellationToken);
await _botStateService.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
}
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
_logger.LogInformation("Running dialog with Message Activity.");
// Run the Dialog with the new message Activity.
await _dialog.Run(turnContext, _botStateService.DialogStateAccessor, cancellationToken);
}
运行方法:
public static async Task Run(this Dialog dialog, ITurnContext turnContext, IStatePropertyAccessor<DialogState> accessor, CancellationToken cancellationToken = default(CancellationToken))
{
var dialogSet = new DialogSet(accessor);
dialogSet.Add(dialog);
var dialogContext = await dialogSet.CreateContextAsync(turnContext, cancellationToken);
var results = await dialogContext.ContinueDialogAsync(cancellationToken);
if (results.Status == DialogTurnStatus.Empty)
{
await dialogContext.BeginDialogAsync(dialog.Id, null, cancellationToken);
}
}
这里的问题是,响应提示后,它将转到BeginDialogAsync而不是ContinueDialogAsync,而这仅是我第一次运行该机器人时发生。如果我以后再触发OptionsDialog,则瀑布步骤将正常运行。