Пример #1
0
        /// <summary>
        /// Generate response with options.
        /// </summary>
        /// <param name="qnaresponse"QnAMaker answer.></param>
        /// <returns>message activity with hero card.</returns>
        public static IMessageActivity GenerateResponseOptions(QnAMakerAnswer qnaresponse)
        {
            var cardButtons = new List <CardAction>();

            foreach (var promptoption in qnaresponse.Options)
            {
                var title = FormatOptionText(promptoption.Option);
                var card  = new CardAction()
                {
                    Value = title,
                    Type  = ActionTypes.ImBack,
                    Title = title,
                };
                cardButtons.Add(card);
            }

            var heroCard = new HeroCard
            {
                Title   = Constants.HeroCardTitle,
                Text    = qnaresponse.Text,
                Buttons = cardButtons,
            };
            var cardActivity = Activity.CreateMessageActivity();

            cardActivity.AttachmentLayout = AttachmentLayoutTypes.Carousel;
            var cardAttachment = heroCard.ToAttachment();

            cardActivity.Attachments.Add(cardAttachment);
            return(cardActivity);
        }
Пример #2
0
        private async Task ShowQnAResponseWithOptions(ITurnContext turnContext, QnAMakerAnswer qnaresponse, ShowQnAResultState qnastatus, CancellationToken cancellationToken = default(CancellationToken))
        {
            var cardActivity = Utils.GenerateResponseOptions(qnaresponse);

            qnastatus.ConsiderState = true;
            qnastatus.QnaAnswer     = qnaresponse;
            qnastatus.NeuroconCount = 0;
            if (qnaresponse.Flowtype == Constants.MetadataValue.Feedback)
            {
                qnastatus.IsFeedback = true;
            }
            else
            {
                qnastatus.IsFeedback = false;
            }

            await _accessors.QnAResultState.SetAsync(turnContext, qnastatus);

            await _accessors.ConversationState.SaveChangesAsync(turnContext);

            await turnContext.SendActivityAsync(cardActivity, cancellationToken);
        }
Пример #3
0
        /// <summary>
        /// Get QnAAnswer from the query result.
        /// </summary>
        /// <param name="response">query result response.</param>
        /// <returns>QnAMaker answer.</returns>
        public static QnAMakerAnswer GetQnAAnswerFromResponse(Microsoft.Bot.Builder.AI.QnA.QueryResult response)
        {
            if (response == null)
            {
                return(null);
            }

            var promptOptionDictionary = new Dictionary <int, PromptOption>();
            var selectedResponse       = response;
            var qnaAnswer = new QnAMakerAnswer();

            qnaAnswer.Text = selectedResponse.Answer ?? null;
            foreach (var metadata in selectedResponse.Metadata)
            {
                if (metadata.Name.Contains(Constants.MetadataName.OptionRequery))
                {
                    var index = metadata.Name.Substring(13);
                    if (int.TryParse(index, out var result))
                    {
                        if (promptOptionDictionary.ContainsKey(result))
                        {
                            promptOptionDictionary[result].Requery = metadata.Value;
                        }
                        else
                        {
                            var optionPrompt = new PromptOption();
                            optionPrompt.Requery = metadata.Value;
                            promptOptionDictionary.Add(result, optionPrompt);
                        }
                    }
                }
                else if (metadata.Name.Contains(Constants.MetadataName.Option))
                {
                    var index = metadata.Name.Substring(6);
                    if (int.TryParse(index, out var result))
                    {
                        if (promptOptionDictionary.ContainsKey(result))
                        {
                            promptOptionDictionary[result].Option = metadata.Value;
                        }
                        else
                        {
                            var optionPrompt = new PromptOption();
                            optionPrompt.Option = metadata.Value;
                            promptOptionDictionary.Add(result, optionPrompt);
                        }
                    }
                }
                else if (metadata.Name.Contains(Constants.MetadataName.QnAId))
                {
                    var index = metadata.Name.Substring(5);
                    if (int.TryParse(index, out var result))
                    {
                        int.TryParse(metadata.Value, out var id);
                        if (promptOptionDictionary.ContainsKey(result))
                        {
                            promptOptionDictionary[result].QnAId = id;
                        }
                        else
                        {
                            var optionPrompt = new PromptOption();
                            optionPrompt.QnAId = id;
                            promptOptionDictionary.Add(result, optionPrompt);
                        }
                    }
                }
                else if (metadata.Name == Constants.MetadataName.Requery)
                {
                    qnaAnswer.Requery = metadata.Value ?? null;
                }
                else if (metadata.Name.Contains(Constants.MetadataName.Name))
                {
                    qnaAnswer.Name = metadata.Value ?? null;
                }
                else if (metadata.Name.Contains(Constants.MetadataName.Parent))
                {
                    qnaAnswer.Parent = metadata.Value ?? null;
                }
                else if (metadata.Name.Contains(Constants.MetadataName.Isroot))
                {
                    qnaAnswer.IsRoot = metadata.Value ?? null;
                }
                else if (metadata.Name.Contains(Constants.MetadataName.Flowtype))
                {
                    qnaAnswer.Flowtype = metadata.Value ?? null;
                }
            }

            foreach (var promptOption in promptOptionDictionary)
            {
                qnaAnswer.Options.Add(promptOption.Value);
            }

            qnaAnswer.IsChitChat = IsResponseChitChat(response);
            return(qnaAnswer);
        }
Пример #4
0
        /// <summary>
        /// Select final response.
        /// </summary>
        /// <param name="responseMultiturn">multiturn response.</param>
        /// <param name="responseGeneral">general response.</param>
        /// <param name="luisresponse">luis response.</param>
        /// <param name="previousAnswer">answer shoen previously.</param>
        /// <returns>selected QnAMaker answer.</returns>

        public static QnAMakerAnswer SelectResponse(QueryResult responseMultiturn, QueryResult responseGeneral, QueryResult luisresponse, QnAMakerAnswer previousAnswer)
        {
            if (responseMultiturn != null)
            {
                var qnaresponse = Utils.GetQnAAnswerFromResponse(responseMultiturn);
                if (previousAnswer == null || !qnaresponse.IsEqual(previousAnswer))
                {
                    return(qnaresponse);
                }
            }

            if (responseGeneral != null)
            {
                var qnaresponse = Utils.GetQnAAnswerFromResponse(responseGeneral);
                if (qnaresponse.IsRoot == null || !Constants.MetadataValue.ExcludeIsroot.Equals(qnaresponse.IsRoot))
                {
                    return(qnaresponse);
                }
            }

            if (luisresponse != null)
            {
                var qnaresponse = Utils.GetQnAAnswerFromResponse(luisresponse);
                if (previousAnswer == null || !qnaresponse.IsEqual(previousAnswer))
                {
                    return(qnaresponse);
                }
            }

            return(null);
        }
Пример #5
0
        private async Task ShowQnAResponseWithText(ITurnContext turnContext, QnAMakerAnswer qnaresponse, ShowQnAResultState qnastatus, CancellationToken cancellationToken = default(CancellationToken))
        {
            qnastatus.ConsiderState = true;
            if (!qnaresponse.IsChitChat)
            {
                qnastatus.NeuroconCount = 0;
            }
            else
            {
                qnastatus.NeuroconCount++;
            }

            qnastatus.QnaAnswer = qnaresponse;
            if (qnaresponse.Flowtype == Constants.MetadataValue.Feedback)
            {
                qnastatus.IsFeedback = true;
            }
            else
            {
                qnastatus.IsFeedback = false;
            }

            await _accessors.QnAResultState.SetAsync(turnContext, qnastatus);

            await _accessors.ConversationState.SaveChangesAsync(turnContext);

            await turnContext.SendActivityAsync(qnaresponse.Text);

            if (!string.IsNullOrEmpty(qnaresponse.Requery) && !qnastatus.IsFeedback)
            {
                var showNextResponseText = true;
                var counter = 0;
                while (showNextResponseText)
                {
                    turnContext.Activity.Text = qnaresponse.Requery;
                    qnastatus = await _accessors.QnAResultState.GetAsync(turnContext, () => new ShowQnAResultState());

                    var response = await GetMultiturnResponseFromKB(turnContext, qnastatus.QnaAnswer);

                    if (response == null)
                    {
                        showNextResponseText = false;
                    }
                    else
                    {
                        qnaresponse = Utils.GetQnAAnswerFromResponse(response);
                        if (qnaresponse == qnastatus.QnaAnswer)
                        {
                            break;
                        }

                        if (qnaresponse.Options != null && qnaresponse.Options.Count != 0)
                        {
                            qnastatus.ConsiderState = true;
                            qnastatus.QnaAnswer     = qnaresponse;
                            qnastatus.NeuroconCount = 0;
                            if (qnaresponse.Flowtype == Constants.MetadataValue.Feedback)
                            {
                                qnastatus.IsFeedback = true;
                            }
                            else
                            {
                                qnastatus.IsFeedback = false;
                            }
                            await _accessors.QnAResultState.SetAsync(turnContext, qnastatus);

                            await _accessors.ConversationState.SaveChangesAsync(turnContext);

                            var cardActivity = Utils.GenerateResponseOptions(qnaresponse);
                            await turnContext.SendActivityAsync(cardActivity, cancellationToken);

                            showNextResponseText = false;
                        }
                        else
                        {
                            qnastatus.ConsiderState = true;
                            qnastatus.QnaAnswer     = qnaresponse;
                            if (!qnaresponse.IsChitChat)
                            {
                                qnastatus.NeuroconCount = 0;
                            }
                            else
                            {
                                qnastatus.NeuroconCount++;
                            }

                            if (qnaresponse.Flowtype == Constants.MetadataValue.Feedback)
                            {
                                qnastatus.IsFeedback = true;
                            }
                            else
                            {
                                qnastatus.IsFeedback = false;
                            }

                            await _accessors.QnAResultState.SetAsync(turnContext, qnastatus);

                            await _accessors.ConversationState.SaveChangesAsync(turnContext);

                            await turnContext.SendActivityAsync(qnaresponse.Text);
                        }

                        counter++;
                        if (counter > Constants.MaxContinuousTextDialogs || qnastatus.IsFeedback || qnastatus.QnaAnswer.Requery == null || qnastatus.NeuroconCount > Constants.ConsecutiveNeuroconAnswersAllowed)
                        {
                            showNextResponseText = false;
                        }
                    }
                }
            }
        }
Пример #6
0
        private async Task <QueryResult> GetMultiturnResponseFromKB(ITurnContext turnContext, QnAMakerAnswer previousAnswer, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (previousAnswer == null || string.IsNullOrEmpty(previousAnswer.Name))
            {
                return(null);
            }

            var qnaOptions = new QnAMakerOptions();
            var metadata   = new Microsoft.Bot.Builder.AI.QnA.Metadata();

            metadata.Name             = Constants.MetadataName.Parent;
            metadata.Value            = previousAnswer.Name;
            qnaOptions.StrictFilters  = new Microsoft.Bot.Builder.AI.QnA.Metadata[] { metadata };
            qnaOptions.Top            = Constants.DefaultTop;
            qnaOptions.ScoreThreshold = Constants.MultiturnThreshold;
            var response = await _services.QnAServices[QnAMakerKey].GetAnswersAsync(turnContext, qnaOptions);

            if (response != null && response.GetLength(0) != 0 && response[0].Score >= Constants.MultiturnThreshold)
            {
                return(response[0]);
            }

            return(null);
        }