对提示对话框未移至下一瀑布步骤的响应

时间:2019-10-12 07:08:49

标签: c# botframework luis

当我第一次运行该应用程序时,我正在执行一些初始化步骤,例如询问姓名和通信模式(聊天或说话),我使用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,则瀑布步骤将正常运行。

0 个答案:

没有答案