예제 #1
0
        public async Task JsonDialogLoad_QnAMakerDialog_ActiveLearning_WithNoneOfAboveQuery()
        {
            var suggestionList = new List<string> { "Q1", "Q2", "Q3" };
            var suggestionActivity = QnACardBuilder.GetSuggestionsCard(suggestionList, "Did you mean:", "None of the above.");
            var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer();

            await BuildQnAMakerTestFlow(nameof(JsonDialogLoad_QnAMakerDialog_ActiveLearning_WithNoneOfAboveQuery))
            .Send("Q11")
                .AssertReply(suggestionActivity, equalityComparer: qnAMakerCardEqualityComparer)
            .Send("None of the above.")
                .AssertReply("Thanks for the feedback.")
            .StartTestAsync();
        }
예제 #2
0
        public async Task JsonDialogLoad_QnAMakerDialog_ActiveLearning_WithNoResponse()
        {
            var suggestionList = new List<string> { "Q1", "Q2", "Q3" };
            var suggestionActivity = QnACardBuilder.GetSuggestionsCard(suggestionList, "Did you mean:", "None of the above.");
            var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer();
            const string noAnswerActivity = "Answers not found in kb.";

            await BuildQnAMakerTestFlow(nameof(JsonDialogLoad_QnAMakerDialog_ActiveLearning_WithNoResponse))
            .Send("Q11")
                .AssertReply(suggestionActivity, equalityComparer: qnAMakerCardEqualityComparer)
            .Send("Q12")
                .AssertReply(noAnswerActivity)
            .StartTestAsync();
        }
예제 #3
0
        public async Task JsonDialogLoad_QnAMakerDialog_ActiveLearning_WithProperResponse()
        {
            var suggestionList = new List <string> {
                "Q1", "Q2", "Q3"
            };
            var suggestionActivity           = QnACardBuilder.GetSuggestionsCard(suggestionList, "Did you mean:", "None of the above.");
            var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer();

            await BuildQnAMakerTestFlow()
            .Send("Q11")
            .AssertReply(suggestionActivity, equalityComparer: qnAMakerCardEqualityComparer)
            .Send("Q1")
            .AssertReply("A1")
            .StartTestAsync();
        }
        private async Task <DialogTurnResult> CallGenerateAnswerAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var qnaMakerOptions = new QnAMakerOptions
            {
                ScoreThreshold = DefaultThreshold,
                Top            = DefaultTopN,
                Context        = new QnARequestContext(),
                QnAId          = 0
            };

            var dialogOptions = GetDialogOptionsValue(stepContext);

            // Getting options
            if (dialogOptions.ContainsKey(QnAOptions))
            {
                qnaMakerOptions = dialogOptions[QnAOptions] as QnAMakerOptions;
                qnaMakerOptions.ScoreThreshold = qnaMakerOptions?.ScoreThreshold ?? DefaultThreshold;
                qnaMakerOptions.Top            = DefaultTopN;
            }

            // Storing the context info
            stepContext.Values[CurrentQuery] = stepContext.Context.Activity.Text;

            // -Check if previous context is present, if yes then put it with the query
            // -Check for id if query is present in reverse index.
            if (!dialogOptions.ContainsKey(QnAContextData))
            {
                dialogOptions[QnAContextData] = new Dictionary <string, int>();
            }
            else
            {
                var previousContextData = dialogOptions[QnAContextData] as Dictionary <string, int>;
                if (dialogOptions[PreviousQnAId] != null)
                {
                    var previousQnAId = Convert.ToInt32(dialogOptions[PreviousQnAId]);

                    if (previousQnAId > 0)
                    {
                        qnaMakerOptions.Context = new QnARequestContext
                        {
                            PreviousQnAId = previousQnAId
                        };

                        qnaMakerOptions.QnAId = 0;
                        if (previousContextData.TryGetValue(stepContext.Context.Activity.Text.ToLower(), out var currentQnAId))
                        {
                            qnaMakerOptions.QnAId = currentQnAId;
                        }
                    }
                }
            }

            // Calling QnAMaker to get response.
            var response = await _services.QnAMakerService.GetAnswersRawAsync(stepContext.Context, qnaMakerOptions).ConfigureAwait(false);

            // Resetting previous query.
            dialogOptions[PreviousQnAId] = -1;
            stepContext.ActiveDialog.State["options"] = dialogOptions;

            // Take this value from GetAnswerResponse
            var isActiveLearningEnabled = response.ActiveLearningEnabled;

            stepContext.Values[QnAData] = new List <QueryResult>(response.Answers);

            // Check if active learning is enabled.
            if (isActiveLearningEnabled && response.Answers.Any() && response.Answers.First().Score <= maximumScoreForLowScoreVariation)
            {
                // Get filtered list of the response that support low score variation criteria.
                response.Answers = _services.QnAMakerService.GetLowScoreVariation(response.Answers);

                if (response.Answers.Count() > 1)
                {
                    var suggestedQuestions = new List <string>();
                    foreach (var qna in response.Answers)
                    {
                        suggestedQuestions.Add(qna.Questions[0]);
                    }

                    // Get active learning suggestion card activity.
                    var qnaDialogResponseOptions = dialogOptions[QnADialogResponseOptions] as QnADialogResponseOptions;
                    var message = QnACardBuilder.GetSuggestionsCard(suggestedQuestions, qnaDialogResponseOptions.ActiveLearningCardTitle, qnaDialogResponseOptions.CardNoMatchText);
                    await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false);

                    return(new DialogTurnResult(DialogTurnStatus.Waiting));
                }
            }

            var result = new List <QueryResult>();

            if (response.Answers.Any())
            {
                result.Add(response.Answers.First());
            }

            stepContext.Values[QnAData] = result;

            // If card is not shown, move to next step with top qna response.
            return(await stepContext.NextAsync(result, cancellationToken).ConfigureAwait(false));
        }
예제 #5
0
        private async Task <DialogTurnResult> CallGenerateAnswerAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var dialogOptions = ObjectPath.GetPathValue <QnAMakerDialogOptions>(stepContext.ActiveDialog.State, Options);

            // Resetting context and QnAId
            dialogOptions.QnAMakerOptions.QnAId   = 0;
            dialogOptions.QnAMakerOptions.Context = new QnARequestContext();

            // Storing the context info
            stepContext.Values[ValueProperty.CurrentQuery] = stepContext.Context.Activity.Text;

            // -Check if previous context is present, if yes then put it with the query
            // -Check for id if query is present in reverse index.
            var previousContextData = ObjectPath.GetPathValue <Dictionary <string, int> >(stepContext.ActiveDialog.State, QnAContextData, new Dictionary <string, int>());
            var previousQnAId       = ObjectPath.GetPathValue <int>(stepContext.ActiveDialog.State, PreviousQnAId, 0);

            if (previousQnAId > 0)
            {
                dialogOptions.QnAMakerOptions.Context = new QnARequestContext
                {
                    PreviousQnAId = previousQnAId
                };

                if (previousContextData.TryGetValue(stepContext.Context.Activity.Text, out var currentQnAId))
                {
                    dialogOptions.QnAMakerOptions.QnAId = currentQnAId;
                }
            }

            // Calling QnAMaker to get response.
            var qnaClient = await GetQnAMakerClientAsync(stepContext).ConfigureAwait(false);

            var response = await qnaClient.GetAnswersRawAsync(stepContext.Context, dialogOptions.QnAMakerOptions).ConfigureAwait(false);

            // Resetting previous query.
            previousQnAId = -1;
            ObjectPath.SetPathValue(stepContext.ActiveDialog.State, PreviousQnAId, previousQnAId);

            // Take this value from GetAnswerResponse
            var isActiveLearningEnabled = response.ActiveLearningEnabled;

            stepContext.Values[ValueProperty.QnAData] = new List <QueryResult>(response.Answers);

            // Check if active learning is enabled.
            // maximumScoreForLowScoreVariation is the score above which no need to check for feedback.
            if (isActiveLearningEnabled && response.Answers.Any() && response.Answers.First().Score <= maximumScoreForLowScoreVariation)
            {
                // Get filtered list of the response that support low score variation criteria.
                response.Answers = qnaClient.GetLowScoreVariation(response.Answers);

                if (response.Answers.Count() > 1)
                {
                    var suggestedQuestions = new List <string>();
                    foreach (var qna in response.Answers)
                    {
                        suggestedQuestions.Add(qna.Questions[0]);
                    }

                    // Get active learning suggestion card activity.
                    var message = QnACardBuilder.GetSuggestionsCard(suggestedQuestions, dialogOptions.ResponseOptions.ActiveLearningCardTitle, dialogOptions.ResponseOptions.CardNoMatchText);
                    await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false);

                    ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions);
                    return(new DialogTurnResult(DialogTurnStatus.Waiting));
                }
            }

            var result = new List <QueryResult>();

            if (response.Answers.Any())
            {
                result.Add(response.Answers.First());
            }

            stepContext.Values[ValueProperty.QnAData] = result;
            ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions);

            // If card is not shown, move to next step with top QnA response.
            return(await stepContext.NextAsync(result, cancellationToken).ConfigureAwait(false));
        }
예제 #6
0
        private async Task <DialogTurnResult> CallGenerateAnswerAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            // clear suggestedQuestions between turns.
            stepContext.State.RemoveValue($"this.suggestedQuestions");

            var dialogOptions = ObjectPath.GetPathValue <QnAMakerDialogOptions>(stepContext.ActiveDialog.State, Options);

            ResetOptions(stepContext, dialogOptions);

            // Storing the context info
            stepContext.Values[ValueProperty.CurrentQuery] = stepContext.Context.Activity.Text;

            // Calling QnAMaker to get response.
            var qnaClient = await GetQnAMakerClientAsync(stepContext).ConfigureAwait(false);

            var response = stepContext.State.GetValue <QueryResults>($"turn.qnaresult{this.GetHashCode()}");

            if (response == null)
            {
                response = await qnaClient.GetAnswersRawAsync(stepContext.Context, dialogOptions.QnAMakerOptions).ConfigureAwait(false);
            }

            // Resetting previous query.
            var previousQnAId = -1;

            ObjectPath.SetPathValue(stepContext.ActiveDialog.State, PreviousQnAId, previousQnAId);

            // Take this value from GetAnswerResponse
            var isActiveLearningEnabled = response.ActiveLearningEnabled;

            stepContext.Values[ValueProperty.QnAData] = new List <QueryResult>(response.Answers);

            // Check if active learning is enabled.
            // MaximumScoreForLowScoreVariation is the score above which no need to check for feedback.
            if (response.Answers.Any() && response.Answers.First().Score <= (ActiveLearningUtils.MaximumScoreForLowScoreVariation / 100))
            {
                // Get filtered list of the response that support low score variation criteria.
                response.Answers = qnaClient.GetLowScoreVariation(response.Answers);

                if (response.Answers.Length > 1 && isActiveLearningEnabled)
                {
                    var suggestedQuestions = new List <string>();
                    foreach (var qna in response.Answers)
                    {
                        suggestedQuestions.Add(qna.Questions[0]);
                    }

                    // Get active learning suggestion card activity.
                    var message = QnACardBuilder.GetSuggestionsCard(suggestedQuestions, dialogOptions.ResponseOptions.ActiveLearningCardTitle, dialogOptions.ResponseOptions.CardNoMatchText);
                    await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false);

                    ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions);
                    stepContext.State.SetValue($"this.suggestedQuestions", suggestedQuestions);
                    return(new DialogTurnResult(DialogTurnStatus.Waiting));
                }
            }

            var result = new List <QueryResult>();

            if (response.Answers.Any())
            {
                result.Add(response.Answers.First());
            }

            stepContext.Values[ValueProperty.QnAData] = result;
            ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions);

            // If card is not shown, move to next step with top QnA response.
            return(await stepContext.NextAsync(result, cancellationToken).ConfigureAwait(false));
        }
예제 #7
0
        private async Task <DialogTurnResult> CallGenerateAnswerAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var qnaMakerOptions = new QnAMakerOptions
            {
                ScoreThreshold = DefaultThreshold,
                Top            = DefaultTopN,
                Context        = new QnARequestContext(),
                QnAId          = 0
            };
            var dialogOptions = GetDialogOptionsValue(stepContext);

            if (dialogOptions.ContainsKey(QnAOptions))
            {
                qnaMakerOptions = dialogOptions[QnAOptions] as QnAMakerOptions;
                qnaMakerOptions.ScoreThreshold = qnaMakerOptions?.ScoreThreshold ?? DefaultThreshold;
                qnaMakerOptions.Top            = DefaultTopN;
            }
            stepContext.Values[CurrentQuery] = stepContext.Context.Activity.Text;
            if (!dialogOptions.ContainsKey(QnAContextData))
            {
                dialogOptions[QnAContextData] = new Dictionary <string, int>();
            }
            else
            {
                var previousContextData = dialogOptions[QnAContextData] as Dictionary <string, int>;
                if (dialogOptions[PreviousQnAId] != null)
                {
                    var previousQnAId = Convert.ToInt32(dialogOptions[PreviousQnAId]);

                    if (previousQnAId > 0)
                    {
                        qnaMakerOptions.Context = new QnARequestContext
                        {
                            PreviousQnAId = previousQnAId
                        };
                        qnaMakerOptions.QnAId = 0;
                        if (previousContextData.TryGetValue(stepContext.Context.Activity.Text.ToLower(), out var currentQnAId))
                        {
                            qnaMakerOptions.QnAId = currentQnAId;
                        }
                    }
                }
            }
            var response = await _services.QnAMakerService.GetAnswersRawAsync(stepContext.Context, qnaMakerOptions).ConfigureAwait(false);

            dialogOptions[PreviousQnAId] = -1;
            stepContext.ActiveDialog.State["options"] = dialogOptions;
            var isActiveLearningEnabled = response.ActiveLearningEnabled;

            stepContext.Values[QnAData] = new List <QueryResult>(response.Answers);
            if (isActiveLearningEnabled && response.Answers.Any() && response.Answers.First().Score <= maximumScoreForLowScoreVariation)
            {
                response.Answers = _services.QnAMakerService.GetLowScoreVariation(response.Answers);
                if (response.Answers.Count() > 1)
                {
                    var suggestedQuestions = new List <string>();
                    foreach (var qna in response.Answers)
                    {
                        suggestedQuestions.Add(qna.Questions[0]);
                    }
                    var qnaDialogResponseOptions = dialogOptions[QnADialogResponseOptions] as QnADialogResponseOptions;
                    var message = QnACardBuilder.GetSuggestionsCard(suggestedQuestions, qnaDialogResponseOptions.ActiveLearningCardTitle, qnaDialogResponseOptions.CardNoMatchText);
                    await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false);

                    return(new DialogTurnResult(DialogTurnStatus.Waiting));
                }
            }
            var result = new List <QueryResult>();

            if (response.Answers.Any())
            {
                result.Add(response.Answers.First());
            }
            stepContext.Values[QnAData] = result;
            return(await stepContext.NextAsync(result, cancellationToken).ConfigureAwait(false));
        }