示例#1
0
        /// <summary>
        /// Every conversation turn for our QnA bot will call this method.
        /// There are no dialogs used, the sample only uses "single turn" processing,
        /// meaning a single request and response, with no stateful conversation.
        /// </summary>
        /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed
        /// for processing this conversation turn. </param>
        /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns>
        /// <seealso cref="BotStateSet"/>
        /// <seealso cref="ConversationState"/>
        /// <seealso cref="IMiddleware"/>
        public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
        {
            // Handle Message activity type, which is the main activity type for shown within a conversational interface
            // Message activities may contain text, speech, interactive cards, and binary or unknown attachments.
            // see https://aka.ms/about-bot-activity-message to learn more about the message and other activity types
            if (turnContext.Activity.Type == ActivityTypes.Message)
            {
                var dialogContext = await dialogs.CreateContextAsync(turnContext, cancellationToken);

                var qnastatus = await _accessors.QnAResultState.GetAsync(turnContext, () => new ShowQnAResultState());

                if (qnastatus.IsFeedback)
                {
                    await HandleFeedbackFlow(qnastatus, turnContext, cancellationToken);
                }

                string requery = null;
                if (qnastatus.ConsiderState)
                {
                    // Call Active Learning Train API
                    if (qnastatus.ActiveLearningAnswer)
                    {
                        _services.QnAServices.TryGetValue(QnAMakerKey, out var qnaservice);
                        var activeLearningData = new ActiveLearningDTO()
                        {
                            hostName     = qnaservice.Endpoint.Host,
                            endpointKey  = qnaservice.Endpoint.EndpointKey,
                            kbid         = qnaservice.Endpoint.KnowledgeBaseId,
                            userId       = turnContext.Activity.From.Id,
                            userQuestion = qnastatus.ActiveLearningUserQuestion,
                        };

                        requery = Utils.GetRequery(qnastatus, turnContext.Activity.Text, activeLearningData);
                        if (requery != null)
                        {
                            TelemetryUtils.LogTrainApiResponse(this._services.TelemetryClient, TelemetryConstants.TrainApiEvent, turnContext.Activity, activeLearningData, requery);
                        }
                    }
                    else
                    {
                        requery = Utils.GetRequery(qnastatus, turnContext.Activity.Text);
                    }

                    if (requery != null)
                    {
                        turnContext.Activity.Text = requery;
                    }
                }

                QueryResult responseGeneral = null, responseLuis = null;

                // Get QnA Answer for multiturn
                var responseMultiturn = await GetMultiturnResponseFromKB(turnContext, qnastatus.QnaAnswer);

                if (responseMultiturn == null)
                {
                    // Get general response from KB
                    responseGeneral = await GetGeneralResponseFromKB(turnContext, qnastatus, true);

                    if (responseGeneral == null)
                    {
                        // Get LUIS intent
                        var luisIntent = await GetLuisIntent(turnContext, Constants.EnableLuis);

                        if (!luisIntent.Equals("None"))
                        {
                            // Get Luis response
                            responseLuis = await GetResponseWithLuisIntent(turnContext, luisIntent);
                        }
                    }
                }

                // choose response
                var qnaresponse = Utils.SelectResponse(responseMultiturn, responseGeneral, responseLuis, qnastatus.QnaAnswer);
                if (qnaresponse != null)
                {
                    if (qnaresponse.Options != null && qnaresponse.Options.Count != 0)
                    {
                        await ShowQnAResponseWithOptions(turnContext, qnaresponse, qnastatus);
                    }
                    else
                    {
                        await ShowQnAResponseWithText(turnContext, qnaresponse, qnastatus);
                    }

                    if (qnastatus.QnaAnswer.Name == Constants.MetadataValue.Redirection)
                    {
                        await ShowRedirection(Constants.RedirectionType.GuidedFlow, turnContext, cancellationToken);
                    }

                    if (qnastatus.NeuroconCount >= Constants.ConsecutiveNeuroconAnswersAllowed)
                    {
                        await ShowRedirection(Constants.RedirectionType.Neurocon, turnContext, cancellationToken);
                    }
                }
                else
                {
                    // get answer from Nurocon
                    var personalitychatanswer = await SendCognitiveServicesResponse(turnContext, cancellationToken, Constants.EnablePersonalityChat);

                    if (personalitychatanswer == string.Empty || personalitychatanswer.Equals(@"Sorry, I don't have a response for that.", StringComparison.OrdinalIgnoreCase))
                    {
                        var msg = @"I don't have an answer for that. Try typing MENU to go back to the main menu";
                        TelemetryUtils.LogNoAnswerEvent(this._services.TelemetryClient, turnContext.Activity);
                        qnastatus.NeuroconCount++;
                        await _accessors.QnAResultState.SetAsync(turnContext, qnastatus);

                        await _accessors.ConversationState.SaveChangesAsync(turnContext);

                        await turnContext.SendActivityAsync(msg, cancellationToken : cancellationToken);

                        if (qnastatus.NeuroconCount >= Constants.ConsecutiveNeuroconAnswersAllowed)
                        {
                            await ShowRedirection(Constants.RedirectionType.Neurocon, turnContext, cancellationToken);
                        }
                    }
                    else
                    {
                        personalitychatanswer   = personalitychatanswer + " [&#x1f6c8;](https://labs.cognitive.microsoft.com/en-us/project-personality-chat \"Auto generated answer using Personality chat. Click to know more\")";
                        qnastatus.ConsiderState = false;
                        qnastatus.QnaAnswer     = null;
                        qnastatus.NeuroconCount++;
                        TelemetryUtils.LogNeuroconResponse(this._services.TelemetryClient, TelemetryConstants.NeuroconEvent, turnContext.Activity, qnastatus, personalitychatanswer);
                        await _accessors.QnAResultState.SetAsync(turnContext, qnastatus);

                        await _accessors.ConversationState.SaveChangesAsync(turnContext);

                        await turnContext.SendActivityAsync(personalitychatanswer, cancellationToken : cancellationToken);

                        if (qnastatus.NeuroconCount >= Constants.ConsecutiveNeuroconAnswersAllowed)
                        {
                            await ShowRedirection(Constants.RedirectionType.Neurocon, turnContext, cancellationToken);
                        }
                    }
                }
            }
            else if (turnContext.Activity.Type == ActivityTypes.ConversationUpdate)
            {
                return;
            }
            else if (turnContext.Activity.Type == ActivityTypes.Event)
            {
                // Send a welcome message to the user.
                var eventActivity = turnContext.Activity.AsEventActivity();
                if (eventActivity.Name == Constants.EventWelcomeMessage)
                {
                    TelemetryUtils.LogWelcomeResponse(this._services.TelemetryClient, "Welcome Event Detected", turnContext.Activity);
                    var dialogContext = await dialogs.CreateContextAsync(turnContext, cancellationToken);

                    var qnastatus = await _accessors.QnAResultState.GetAsync(turnContext, () => new ShowQnAResultState());

                    qnastatus.ConsiderState  = false;
                    qnastatus.QnaAnswer.Text = Constants.WelcomeQuestion;
                    qnastatus.QnaAnswer.Name = Constants.MetadataValue.Welcome;
                    await _accessors.QnAResultState.SetAsync(turnContext, qnastatus);

                    await _accessors.ConversationState.SaveChangesAsync(turnContext);
                    await SendWelcomeMessageAsync(turnContext, cancellationToken);
                }
            }
            else
            {
                await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected", cancellationToken : cancellationToken);
            }
        }
示例#2
0
        /// <summary>
        /// get requery text.
        /// </summary>
        /// <param name="qnastatus">qnastatus.</param>
        /// <param name="activityText">activity text.</param>
        /// <param name="activeLearningdata">activeleraning data.</param>
        /// <returns></returns>
        public static string GetRequery(ShowQnAResultState qnastatus, string activityText, ActiveLearningDTO activeLearningdata = null)
        {
            string requery = null;

            if (qnastatus.QnaAnswer.Options != null && qnastatus.QnaAnswer.Options.Count != 0)
            {
                foreach (var promptoption in qnastatus.QnaAnswer.Options)
                {
                    if (promptoption.Option.Equals(activityText, StringComparison.CurrentCultureIgnoreCase))
                    {
                        requery = string.IsNullOrEmpty(promptoption.Requery) ? promptoption.Option : promptoption.Requery;

                        // call train API if active learning
                        if (qnastatus.ActiveLearningAnswer == true && activeLearningdata != null)
                        {
                            qnastatus.ActiveLearningAnswer = false;
                            activeLearningdata.qnaId       = promptoption.QnAId;
                            ActiveLearning.CallTrainApi(activeLearningdata);
                            qnastatus.ActiveLearningUserQuestion = null;
                        }

                        break;
                    }
                }
            }
            else
            {
                requery = string.IsNullOrEmpty(qnastatus.QnaAnswer.Requery) ? null : qnastatus.QnaAnswer.Requery;
            }

            return(requery);
        }
        /// <summary>
        /// Log train api call.
        /// </summary>
        /// <param name="telemetryClient">telemetry client.</param>
        /// <param name="eventName">event name.</param>
        /// <param name="activity">sctivity.</param>
        /// <param name="activeLearningData">active learning data.</param>
        /// <param name="requery">requery.</param>
        public static void LogTrainApiResponse(Microsoft.ApplicationInsights.TelemetryClient telemetryClient, string eventName, Activity activity, ActiveLearningDTO activeLearningData, string requery)
        {
            var properties = new Dictionary <string, string>()
            {
                { TelemetryConstants.EndpointKey, activeLearningData.endpointKey },
                { TelemetryConstants.HostName, activeLearningData.hostName },
                { TelemetryConstants.Kbid, activeLearningData.kbid },
                { TelemetryConstants.UserQuestion, activeLearningData.userQuestion },
                { TelemetryConstants.UserSelectedPrompt, requery },
            };

            AddBasicProperties(properties, activity);
            telemetryClient.TrackEvent(eventName, properties);
        }