Beispiel #1
0
        private async Task <DialogTurnResult> CheckForMultiTurnPrompt(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            if (stepContext.Result is List <QueryResult> response && response.Count > 0)
            {
                // -Check if context is present and prompt exists
                // -If yes: Add reverse index of prompt display name and its corresponding qna id
                // -Set PreviousQnAId as answer.Id
                // -Display card for the prompt
                // -Wait for the reply
                // -If no: Skip to next step

                var answer = response.First();

                if (answer.Context != null && answer.Context.Prompts.Count() > 0)
                {
                    var dialogOptions            = GetDialogOptionsValue(stepContext);
                    var qnaDialogResponseOptions = dialogOptions[QnADialogResponseOptions] as QnADialogResponseOptions;
                    var previousContextData      = new Dictionary <string, int>();
                    if (dialogOptions.ContainsKey(QnAContextData))
                    {
                        previousContextData = dialogOptions[QnAContextData] as Dictionary <string, int>;
                    }

                    foreach (var prompt in answer.Context.Prompts)
                    {
                        previousContextData.Add(prompt.DisplayText, prompt.QnaId);
                    }

                    dialogOptions[QnAContextData]             = previousContextData;
                    dialogOptions[PreviousQnAId]              = answer.Id;
                    stepContext.ActiveDialog.State["options"] = dialogOptions;

                    // Get multi-turn prompts card activity.
                    var message = QnACardBuilder.GetQnAPromptsCard(answer, qnaDialogResponseOptions.CardNoMatchText);
                    await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false);

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

            return(await stepContext.NextAsync(stepContext.Result, cancellationToken).ConfigureAwait(false));
        }
Beispiel #2
0
        private async Task <DialogTurnResult> CallGenerateAnswerAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var qnaMakerOptions = new QnAMakerOptions
            {
                ScoreThreshold = DefaultThreshold,
                Top            = DefaultTopN
            };

            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
                        };

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

            // Calling QnAMaker to get response.
            var response = await _qnaMakerClient.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.
            // 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 = _qnaMakerClient.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));
        }