/// <summary> /// Return results of the call to QnA Maker. /// </summary> /// <param name="dialogContext">Context object containing information for a single turn of conversation with a user.</param> /// <param name="activity">The incoming activity received from the user. The Text property value is used as the query text for QnA Maker.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> /// <param name="telemetryProperties">Additional properties to be logged to telemetry with the LuisResult event.</param> /// <param name="telemetryMetrics">Additional metrics to be logged to telemetry with the LuisResult event.</param> /// <returns>A <see cref="RecognizerResult"/> containing the QnA Maker result.</returns> public override async Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken, Dictionary <string, string> telemetryProperties = null, Dictionary <string, double> telemetryMetrics = null) { // Identify matched intents var recognizerResult = new RecognizerResult { Text = activity.Text, Intents = new Dictionary <string, IntentScore>(), }; if (string.IsNullOrEmpty(activity.Text)) { recognizerResult.Intents.Add("None", new IntentScore()); return(recognizerResult); } var filters = new List <Metadata>(); if (IncludeDialogNameInMetadata.GetValue(dialogContext.State)) { filters.Add(new Metadata { Name = "dialogName", Value = dialogContext.ActiveDialog.Id }); } // if there is $qna.metadata set add to filters var externalMetadata = Metadata?.GetValue(dialogContext.State); if (externalMetadata != null) { filters.AddRange(externalMetadata); } // Calling QnAMaker to get response. var qnaClient = await GetQnAMakerClientAsync(dialogContext).ConfigureAwait(false); var answers = await qnaClient.GetAnswersAsync( dialogContext.Context, new QnAMakerOptions { Context = Context?.GetValue(dialogContext.State), ScoreThreshold = Threshold.GetValue(dialogContext.State), StrictFilters = filters.ToArray(), Top = Top.GetValue(dialogContext.State), QnAId = QnAId.GetValue(dialogContext.State), RankerType = RankerType.GetValue(dialogContext.State), IsTest = IsTest }, null).ConfigureAwait(false); if (answers.Any()) { QueryResult topAnswer = null; foreach (var answer in answers) { if (topAnswer == null || answer.Score > topAnswer.Score) { topAnswer = answer; } } if (topAnswer.Answer.Trim().ToUpperInvariant().StartsWith(IntentPrefix.ToUpperInvariant(), StringComparison.Ordinal)) { recognizerResult.Intents.Add(topAnswer.Answer.Trim().Substring(IntentPrefix.Length).Trim(), new IntentScore { Score = topAnswer.Score }); } else { recognizerResult.Intents.Add(QnAMatchIntent, new IntentScore { Score = topAnswer.Score }); } var answerArray = new JArray(); answerArray.Add(topAnswer.Answer); ObjectPath.SetPathValue(recognizerResult, "entities.answer", answerArray); var instance = new JArray(); instance.Add(JObject.FromObject(topAnswer)); ObjectPath.SetPathValue(recognizerResult, "entities.$instance.answer", instance); recognizerResult.Properties["answers"] = answers; } else { recognizerResult.Intents.Add("None", new IntentScore { Score = 1.0f }); } TrackRecognizerResult(dialogContext, "QnAMakerRecognizerResult", FillRecognizerResultTelemetryProperties(recognizerResult, telemetryProperties), telemetryMetrics); return(recognizerResult); }
public async override Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken = default, Dictionary <System.String, System.String> telemetryProperties = null, Dictionary <System.String, System.Double> telemetryMetrics = null) { var qluceneEngine = await QLuceneEngineCache.GetEngine(dialogContext, this.KnowledgeBase).ConfigureAwait(false); var threshold = Threshold.GetValue(dialogContext); var recognizerResult = new RecognizerResult { Text = activity.Text, Intents = new Dictionary <string, IntentScore>(), }; if (string.IsNullOrEmpty(activity.Text)) { recognizerResult.Intents.Add("None", new IntentScore()); return(recognizerResult); } var rankerType = RankerType?.GetValue(dialogContext.State); var strictFiltersCompoundOperationType = StrictFiltersCompoundOperationType?.GetValue(dialogContext.State); var strictFilters = new List <Metadata>(); var context = Context?.GetValue(dialogContext.State); bool includeDialogNameInMetadata = IncludeDialogNameInMetadata.GetValue(dialogContext.State); if (includeDialogNameInMetadata) { strictFilters.Add(new Metadata { Name = "dialogName", Value = dialogContext.ActiveDialog.Id }); } // if there is $qna.metadata set add to filters var externalMetadata = StrictFilters?.GetValue(dialogContext.State); if (externalMetadata != null) { strictFilters.AddRange(externalMetadata); } var topAnswer = qluceneEngine.GetAnswers(activity.Text, strictFilters: strictFilters.ToArray(), context: context, threshold: threshold, rankerType: rankerType, strictFiltersCompoundOperationType: strictFiltersCompoundOperationType); if (topAnswer != null) { if (topAnswer.Answer.Trim().ToUpperInvariant().StartsWith(IntentPrefix.ToUpperInvariant(), StringComparison.Ordinal)) { recognizerResult.Intents.Add(topAnswer.Answer.Trim().Substring(IntentPrefix.Length).Trim(), new IntentScore { Score = topAnswer.Score }); } else { recognizerResult.Intents.Add(QnAMatchIntent, new IntentScore { Score = topAnswer.Score }); } var answerArray = new JArray(); answerArray.Add(topAnswer.Answer); ObjectPath.SetPathValue(recognizerResult, "entities.answer", answerArray); var instance = new JArray(); var data = JObject.FromObject(topAnswer); data["startIndex"] = 0; data["endIndex"] = activity.Text.Length; instance.Add(data); ObjectPath.SetPathValue(recognizerResult, "entities.$instance.answer", instance); // recognizerResult.Properties["answers"] = answers; } else { recognizerResult.Intents.Add("None", new IntentScore { Score = 1.0f }); } var traceInfo = new { recognizerResult, options = new { id = this.Id, knowledgeBase = this.KnowledgeBase, scoreThreshold = threshold, context, rankerType, strictFilters = strictFilters.ToArray(), includeDialogNameInMetadata, strictFiltersCompoundOperationType } }; await dialogContext.Context.TraceActivityAsync(nameof(QLuceneRecognizer), traceInfo, TraceType, TraceLabel, cancellationToken).ConfigureAwait(false); return(recognizerResult); }