From a82c9fa0031acc11482c69a8839c7ea12a34e012 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Thu, 14 May 2020 13:27:30 +0530 Subject: [PATCH 01/60] AnswerSpanRequest property in Request. --- .../AnswerSpanRequest.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs new file mode 100644 index 0000000000..a5136a4f99 --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Bot.Builder.AI.QnA +{ + public class AnswerSpanRequest + { + public boolean enable { get; set; } + + public int topAnswersWithSpan { get; set; } + } +} From abf369a7b97fb6ace4e31e89c3dc5ab29fd4c733 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Thu, 14 May 2020 13:46:27 +0530 Subject: [PATCH 02/60] Answer span changes for request and response data sstructures --- .../Models/AnswerSpan.cs | 16 ++++++++++++++++ .../Models/QnAMakerTraceInfo.cs | 11 ++++++++++- .../Models/QueryResult.cs | 9 +++++++++ .../QnAMakerOptions.cs | 9 +++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs new file mode 100644 index 0000000000..7f351cad9d --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Bot.Builder.AI.QnA +{ + public class AnswerSpan + { + public string text { get; set; } + + public float score { get; set; } + + public int startIndex { get; set; } + + public int endIndex { get; set; } + } +} diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs index fd237e68c7..280f79f9d6 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs @@ -103,9 +103,18 @@ public class QnAMakerTraceInfo /// [JsonProperty("rankerType")] public string RankerType { get; set; } - + [Obsolete("This property is no longer used and will be ignored")] [JsonIgnore] public Metadata[] MetadataBoost { get; set; } + + /// + /// Gets or sets AnswerSpanRequest of the previous turn. + /// + /// + /// The AnswerSpanRequest. + /// + [JsonProperty("answerSpanRequest")] + public AnswerSpanRequest answerSpanRequest { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs index 99ec649dd3..06b0cfdba0 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs @@ -76,5 +76,14 @@ public class QueryResult /// [JsonProperty(PropertyName = "context")] public QnAResponseContext Context { get; set; } + + /// + /// Gets or sets AnswerSpan of the previous turn. + /// + /// + /// The answerspan value. + /// + [JsonProperty("answerSpan")] + public AnswerSpan answerSpan { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs index 4c5307245a..02f27a4c9b 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs @@ -92,5 +92,14 @@ public QnAMakerOptions() /// [JsonProperty("rankerType")] public string RankerType { get; set; } + + /// + /// Gets or sets AnswerSpanRequest of the previous turn. + /// + /// + /// The context of previous turn. + /// + [JsonProperty("answerSpanRequest")] + public AnswerSpanRequest AnswerSpanRequest { get; set; } } } From f4c8c4a63dbfe69b5ee1dd5eca7ad5a020dbdc3c Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Thu, 14 May 2020 14:02:07 +0530 Subject: [PATCH 03/60] Request and Result object conversion --- .../AnswerSpanRequest.cs | 20 +++++++++-- .../Models/AnswerSpan.cs | 36 +++++++++++++++++-- .../Models/QnAMakerTraceInfo.cs | 2 +- .../Models/QueryResult.cs | 2 +- .../Utils/GenerateAnswerUtils.cs | 9 +++-- 5 files changed, 59 insertions(+), 10 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index a5136a4f99..bac3742c72 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -1,13 +1,29 @@ using System; using System.Collections.Generic; using System.Text; +using Newtonsoft.Json; namespace Microsoft.Bot.Builder.AI.QnA { public class AnswerSpanRequest { - public boolean enable { get; set; } + /// + /// Gets or sets the enablet. + /// + /// + /// The answer text. + /// + [JsonProperty("enable")] + public Boolean Enable { get; set; } - public int topAnswersWithSpan { get; set; } + /// + /// Gets or sets the TopAnswersWithSpan. + /// + /// + /// The answer TopAnswersWithSpan. + /// + [JsonProperty("topAnswersWithSpan")] + + public int TopAnswersWithSpan { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs index 7f351cad9d..cd9edd97ac 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs @@ -1,16 +1,46 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using Newtonsoft.Json; + namespace Microsoft.Bot.Builder.AI.QnA { public class AnswerSpan { + /// + /// Gets or sets the answer text. + /// + /// + /// The answer text. + /// + [JsonProperty("text")] public string text { get; set; } - public float score { get; set; } + /// + /// Gets or sets the answer score. + /// + /// + /// The answer score. + /// + [JsonProperty("score")] + public float Score { get; set; } - public int startIndex { get; set; } + /// + /// Gets or sets the answer startIndex. + /// + /// + /// The answer startIndex. + /// + [JsonProperty("startIndex")] + public int StartIndex { get; set; } - public int endIndex { get; set; } + /// + /// Gets or sets the answer endIndex. + /// + /// + /// The answer endIndex. + /// + [JsonProperty("endIndex")] + public int EndIndex { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs index 280f79f9d6..264963da49 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs @@ -115,6 +115,6 @@ public class QnAMakerTraceInfo /// The AnswerSpanRequest. /// [JsonProperty("answerSpanRequest")] - public AnswerSpanRequest answerSpanRequest { get; set; } + public AnswerSpanRequest AnswerSpanRequest { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs index 06b0cfdba0..ea8d86a5ae 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs @@ -84,6 +84,6 @@ public class QueryResult /// The answerspan value. /// [JsonProperty("answerSpan")] - public AnswerSpan answerSpan { get; set; } + public AnswerSpan AnswerSpan { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs index 5312ed5521..ce40735590 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs @@ -175,6 +175,7 @@ private QnAMakerOptions HydrateOptions(QnAMakerOptions queryOptions) hydratedOptions.QnAId = queryOptions.QnAId; hydratedOptions.IsTest = queryOptions.IsTest; hydratedOptions.RankerType = queryOptions.RankerType != null ? queryOptions.RankerType : RankerTypes.DefaultRankerType; + hydratedOptions.AnswerSpanRequest = queryOptions.AnswerSpanRequest; } return hydratedOptions; @@ -193,7 +194,8 @@ private async Task QueryQnaServiceAsync(Activity messageActivity, context = options.Context, qnaId = options.QnAId, isTest = options.IsTest, - rankerType = options.RankerType + rankerType = options.RankerType, + answerSpanRequest = options.AnswerSpanRequest }, Formatting.None); var httpRequestHelper = new HttpRequestUtils(httpClient); @@ -213,11 +215,12 @@ private async Task EmitTraceInfoAsync(ITurnContext turnContext, Activity message KnowledgeBaseId = _endpoint.KnowledgeBaseId, ScoreThreshold = options.ScoreThreshold, Top = options.Top, - StrictFilters = options.StrictFilters, + StrictFilters = options.StrictFilters, Context = options.Context, QnAId = options.QnAId, IsTest = options.IsTest, - RankerType = options.RankerType + RankerType = options.RankerType, + AnswerSpanRequest = options.AnswerSpanRequest }; var traceActivity = Activity.CreateTraceActivity(QnAMaker.QnAMakerName, QnAMaker.QnAMakerTraceType, traceInfo, QnAMaker.QnAMakerTraceLabel); await turnContext.SendActivityAsync(traceActivity).ConfigureAwait(false); From 96df775aa2ea01b14df603e71ab06dc3251dbe63 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Thu, 14 May 2020 14:04:56 +0530 Subject: [PATCH 04/60] datatype definition change from boolean to bool for enable AnswerSpan --- libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index bac3742c72..8f278f2881 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -14,7 +14,7 @@ public class AnswerSpanRequest /// The answer text. /// [JsonProperty("enable")] - public Boolean Enable { get; set; } + public bool Enable { get; set; } /// /// Gets or sets the TopAnswersWithSpan. @@ -23,7 +23,6 @@ public class AnswerSpanRequest /// The answer TopAnswersWithSpan. /// [JsonProperty("topAnswersWithSpan")] - public int TopAnswersWithSpan { get; set; } } } From 9a37d250f76ea7adc7d74949b5322f2719f45033 Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Fri, 15 May 2020 22:52:52 +0530 Subject: [PATCH 05/60] Text --- libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs index cd9edd97ac..bc2de3d5c5 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs @@ -14,7 +14,7 @@ public class AnswerSpan /// The answer text. /// [JsonProperty("text")] - public string text { get; set; } + public string Text { get; set; } /// /// Gets or sets the answer score. From c157ca31d0ada49d2590f45776fab929a25a7a7e Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Fri, 15 May 2020 22:54:06 +0530 Subject: [PATCH 06/60] spaces --- libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index 8f278f2881..a58dad23ed 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -5,7 +5,7 @@ namespace Microsoft.Bot.Builder.AI.QnA { - public class AnswerSpanRequest + public class AnswerSpanRequest { /// /// Gets or sets the enablet. From b058dddd26dfc70068f4b06a241877983befd970 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Mon, 18 May 2020 17:15:46 +0530 Subject: [PATCH 07/60] MRCEnable instead of AnswerSpanRequest --- .../QnAMakerOptions.cs | 8 ++++---- .../Utils/GenerateAnswerUtils.cs | 14 +++++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs index 02f27a4c9b..9d3859bc68 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs @@ -94,12 +94,12 @@ public QnAMakerOptions() public string RankerType { get; set; } /// - /// Gets or sets AnswerSpanRequest of the previous turn. + /// Gets or sets MRCEnable of the previous turn. /// /// - /// The context of previous turn. + /// To enable MRC /// - [JsonProperty("answerSpanRequest")] - public AnswerSpanRequest AnswerSpanRequest { get; set; } + [JsonProperty("MRCEnable")] + public bool MRCEnable { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs index ce40735590..23f762504f 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs @@ -169,13 +169,13 @@ private QnAMakerOptions HydrateOptions(QnAMakerOptions queryOptions) if (queryOptions.StrictFilters?.Length > 0) { hydratedOptions.StrictFilters = queryOptions.StrictFilters; - } + } hydratedOptions.Context = queryOptions.Context; hydratedOptions.QnAId = queryOptions.QnAId; hydratedOptions.IsTest = queryOptions.IsTest; hydratedOptions.RankerType = queryOptions.RankerType != null ? queryOptions.RankerType : RankerTypes.DefaultRankerType; - hydratedOptions.AnswerSpanRequest = queryOptions.AnswerSpanRequest; + hydratedOptions.MRCEnable = queryOptions.MRCEnable; } return hydratedOptions; @@ -184,18 +184,20 @@ private QnAMakerOptions HydrateOptions(QnAMakerOptions queryOptions) private async Task QueryQnaServiceAsync(Activity messageActivity, QnAMakerOptions options) { var requestUrl = $"{_endpoint.Host}/knowledgebases/{_endpoint.KnowledgeBaseId}/generateanswer"; + var answerSpanRequest = new AnswerSpanRequest(); + answerSpanRequest.Enable = options.MRCEnable; var jsonRequest = JsonConvert.SerializeObject( new { question = messageActivity.Text, top = options.Top, - strictFilters = options.StrictFilters, + strictFilters = options.StrictFilters, scoreThreshold = options.ScoreThreshold, context = options.Context, qnaId = options.QnAId, isTest = options.IsTest, rankerType = options.RankerType, - answerSpanRequest = options.AnswerSpanRequest + answerSpanRequest = answerSpanRequest }, Formatting.None); var httpRequestHelper = new HttpRequestUtils(httpClient); @@ -208,6 +210,8 @@ private async Task QueryQnaServiceAsync(Activity messageActivity, private async Task EmitTraceInfoAsync(ITurnContext turnContext, Activity messageActivity, QueryResult[] result, QnAMakerOptions options) { + var answerSpanRequest = new AnswerSpanRequest(); + answerSpanRequest.Enable = options.MRCEnable; var traceInfo = new QnAMakerTraceInfo { Message = (Activity)messageActivity, @@ -220,7 +224,7 @@ private async Task EmitTraceInfoAsync(ITurnContext turnContext, Activity message QnAId = options.QnAId, IsTest = options.IsTest, RankerType = options.RankerType, - AnswerSpanRequest = options.AnswerSpanRequest + AnswerSpanRequest = answerSpanRequest }; var traceActivity = Activity.CreateTraceActivity(QnAMaker.QnAMakerName, QnAMaker.QnAMakerTraceType, traceInfo, QnAMaker.QnAMakerTraceLabel); await turnContext.SendActivityAsync(traceActivity).ConfigureAwait(false); From 202db55c435a0ee23a6a431e3dba17b39b0a7ce3 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Thu, 21 May 2020 00:39:25 +0530 Subject: [PATCH 08/60] Answerspan text set to answer for MRC --- .../Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs | 5 +++++ libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 32faf95021..de55d9c172 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -504,6 +504,11 @@ private async Task CallGenerateAnswerAsync(WaterfallStepContex var result = new List(); if (response.Answers.Any()) { + if (response.Answers.First() != null && response.Answers.First().AnswerSpan != null && !string.IsNullOrEmpty(response.Answers.First().AnswerSpan.Text)) + { + response.Answers.First().Answer = response.Answers.First().AnswerSpan.Text; + } + result.Add(response.Answers.First()); } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs index 9d3859bc68..ab040d7ff6 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs @@ -94,12 +94,12 @@ public QnAMakerOptions() public string RankerType { get; set; } /// - /// Gets or sets MRCEnable of the previous turn. + /// Gets or sets a value indicating whether MRCEnable of the previous turn. /// /// - /// To enable MRC + /// To enable MRC. /// - [JsonProperty("MRCEnable")] + [JsonProperty("mRCEnable")] public bool MRCEnable { get; set; } } } From e131a74315594ec1bb34f75eaa05e2060c7944c5 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Thu, 21 May 2020 01:20:58 +0530 Subject: [PATCH 09/60] Mock changes --- .../Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs | 11 +---------- .../QnAMakerRecognizerTests.cs | 8 ++++---- .../QnAMakerTests.cs | 8 ++++---- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index a58dad23ed..8eea8391a8 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -8,21 +8,12 @@ namespace Microsoft.Bot.Builder.AI.QnA public class AnswerSpanRequest { /// - /// Gets or sets the enablet. + /// Gets or sets a value indicating whether gets or sets the enablet. /// /// /// The answer text. /// [JsonProperty("enable")] public bool Enable { get; set; } - - /// - /// Gets or sets the TopAnswersWithSpan. - /// - /// - /// The answer TopAnswersWithSpan. - /// - [JsonProperty("topAnswersWithSpan")] - public int TopAnswersWithSpan { get; set; } } } diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs index a6e1ce3836..242a484707 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs @@ -59,16 +59,16 @@ public AdaptiveDialog QnAMakerRecognizer_DialogBase() { var mockHttp = new MockHttpMessageHandler(); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_ReturnsAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") + .WithContent("{\"question\":\"QnaMaker_ReturnsAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_ReturnsNoAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") + .WithContent("{\"question\":\"QnaMaker_ReturnsNoAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsNoAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_TopNAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") + .WithContent("{\"question\":\"QnaMaker_TopNAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_ReturnsAnswerWithIntent\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") + .WithContent("{\"question\":\"QnaMaker_ReturnsAnswerWithIntent\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswerWithIntent.json")); return CreateQnAMakerActionDialog(mockHttp); diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index 3b45de8dab..abfa4578e2 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -40,11 +40,11 @@ public class QnAMakerTests public AdaptiveDialog QnAMakerAction_ActiveLearningDialogBase() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetTrainRequestUrl()) .Respond(HttpStatusCode.NoContent, "application/json", "{ }"); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); return CreateQnAMakerActionDialog(mockHttp); @@ -106,9 +106,9 @@ await CreateFlow(rootDialog) public AdaptiveDialog QnAMakerAction_MultiTurnDialogBase() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"I have issues related to KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"I have issues related to KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnAnswer_withPrompts.json")); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Accidently deleted KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":27,\"previousUserQuery\":\"\"},\"qnaId\":1,\"isTest\":false,\"rankerType\":\"Default\"}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Accidently deleted KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":27,\"previousUserQuery\":\"\"},\"qnaId\":1,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnAnswer_MultiTurnLevel1.json")); return CreateQnAMakerActionDialog(mockHttp); From 57a5c5309115644f965abc346f3369aa034aa8e5 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Fri, 22 May 2020 02:23:13 +0530 Subject: [PATCH 10/60] Review comments changes --- .../Dialogs/QnAMakerDialog.cs | 50 ++++++++++++++--- .../QnADialogResponseOptions.cs | 12 ++++ .../QnAMakerOptions.cs | 4 +- .../Utils/GenerateAnswerUtils.cs | 8 +-- .../Utils/QnACardBuilder.cs | 56 ++++++++++++++++++- 5 files changed, 116 insertions(+), 14 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index de55d9c172..88db3c67a7 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -504,15 +504,11 @@ private async Task CallGenerateAnswerAsync(WaterfallStepContex var result = new List(); if (response.Answers.Any()) { - if (response.Answers.First() != null && response.Answers.First().AnswerSpan != null && !string.IsNullOrEmpty(response.Answers.First().AnswerSpan.Text)) - { - response.Answers.First().Answer = response.Answers.First().AnswerSpan.Text; - } - 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. @@ -630,8 +626,23 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC ObjectPath.SetPathValue(stepContext.ActiveDialog.State, PreviousQnAId, answer.Id); ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions); + int contentChoice = -1; + + if (answer.AnswerSpan != null && !string.IsNullOrEmpty(answer.AnswerSpan.Text)) + { + if (dialogOptions.ResponseOptions.ContentChoice.Equals(QnADialogResponseOptions.PreciseAnswer)) + { + contentChoice = 0; + } + + if (dialogOptions.ResponseOptions.ContentChoice.Equals(QnADialogResponseOptions.Both)) + { + contentChoice = 1; + } + } + // Get multi-turn prompts card activity. - var message = QnACardBuilder.GetQnAPromptsCard(answer, dialogOptions.ResponseOptions.CardNoMatchText); + var message = QnACardBuilder.GetQnAPromptsCard(answer, dialogOptions.ResponseOptions.CardNoMatchText, contentChoice); await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false); return new DialogTurnResult(DialogTurnStatus.Waiting); @@ -641,6 +652,13 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC return await stepContext.NextAsync(stepContext.Result, cancellationToken).ConfigureAwait(false); } + /// + /// Gets the options the dialog will use to display query results to the user. + /// + /// The for the current turn of conversation. + /// The for the current turn of conversation. + /// A representing the asynchronous operation. + /// If the task is successful, the result contains the response options to use. private async Task DisplayQnAResultAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var dialogOptions = ObjectPath.GetPathValue(stepContext.ActiveDialog.State, Options); @@ -672,7 +690,25 @@ private async Task DisplayQnAResultAsync(WaterfallStepContext // If response is present then show that response, else default answer. if (stepContext.Result is List response && response.Count > 0) { - await stepContext.Context.SendActivityAsync(response.First().Answer, cancellationToken: cancellationToken).ConfigureAwait(false); + var firstAnswer = response.First(); + var answer = firstAnswer.Answer; + int contentChoice = -1; + + if (firstAnswer.AnswerSpan != null && !string.IsNullOrEmpty(firstAnswer.AnswerSpan.Text)) + { + if (dialogOptions.ResponseOptions.ContentChoice.Equals(QnADialogResponseOptions.PreciseAnswer)) + { + contentChoice = 0; + } + + if (dialogOptions.ResponseOptions.ContentChoice.Equals(QnADialogResponseOptions.Both)) + { + contentChoice = 1; + } + } + + var message = QnACardBuilder.GetAnswerSpanCard(firstAnswer, contentChoice); + await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false); } else { diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs index f4d9d28576..d9eee18037 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs @@ -10,6 +10,10 @@ namespace Microsoft.Bot.Builder.AI.QnA /// public class QnADialogResponseOptions { + public const string PreciseAnswer = "PreciseAnswer"; + + public const string Both = "Both"; + /// /// Gets or sets get or set for Active learning card title. /// @@ -41,5 +45,13 @@ public class QnADialogResponseOptions /// Get or set for Card no match response. /// public Activity CardNoMatchResponse { get; set; } + + /// + /// Gets or sets get or set for MRCAnswerSpanRenderingOption. + /// + /// + /// Get or set for Card no match MRCAnswerSpanRenderingOption. + /// + public string ContentChoice { get; set; } = PreciseAnswer; } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs index ab040d7ff6..68f86a736e 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs @@ -99,7 +99,7 @@ public QnAMakerOptions() /// /// To enable MRC. /// - [JsonProperty("mRCEnable")] - public bool MRCEnable { get; set; } + [JsonProperty("enableMRC")] + public bool EnablePreciseAnswer { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs index 23f762504f..cbf86dab8b 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs @@ -153,7 +153,7 @@ private static void ValidateOptions(QnAMakerOptions options) private QnAMakerOptions HydrateOptions(QnAMakerOptions queryOptions) { var hydratedOptions = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(this.Options)); - + if (queryOptions != null) { if (queryOptions.ScoreThreshold != hydratedOptions.ScoreThreshold && queryOptions.ScoreThreshold != 0) @@ -175,7 +175,7 @@ private QnAMakerOptions HydrateOptions(QnAMakerOptions queryOptions) hydratedOptions.QnAId = queryOptions.QnAId; hydratedOptions.IsTest = queryOptions.IsTest; hydratedOptions.RankerType = queryOptions.RankerType != null ? queryOptions.RankerType : RankerTypes.DefaultRankerType; - hydratedOptions.MRCEnable = queryOptions.MRCEnable; + hydratedOptions.EnablePreciseAnswer = queryOptions.EnablePreciseAnswer; } return hydratedOptions; @@ -185,7 +185,7 @@ private async Task QueryQnaServiceAsync(Activity messageActivity, { var requestUrl = $"{_endpoint.Host}/knowledgebases/{_endpoint.KnowledgeBaseId}/generateanswer"; var answerSpanRequest = new AnswerSpanRequest(); - answerSpanRequest.Enable = options.MRCEnable; + answerSpanRequest.Enable = options.EnablePreciseAnswer; var jsonRequest = JsonConvert.SerializeObject( new { @@ -211,7 +211,7 @@ private async Task QueryQnaServiceAsync(Activity messageActivity, private async Task EmitTraceInfoAsync(ITurnContext turnContext, Activity messageActivity, QueryResult[] result, QnAMakerOptions options) { var answerSpanRequest = new AnswerSpanRequest(); - answerSpanRequest.Enable = options.MRCEnable; + answerSpanRequest.Enable = options.EnablePreciseAnswer; var traceInfo = new QnAMakerTraceInfo { Message = (Activity)messageActivity, diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index e052d36a16..a40f8b55f3 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -81,8 +81,9 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, /// /// Result to be dispalyed as prompts. /// No match text. + /// renderingchoice. /// IMessageActivity. - public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText) + public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText, int renderingOption) { if (result == null) { @@ -115,6 +116,19 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card Buttons = buttonList }; + // For content choice Both Precise and Content + if (renderingOption == 1) + { + plCard.Text = result.Answer; + chatActivity.Text = result.AnswerSpan.Text; + } + + // For content choice Precise only + if (renderingOption == 0) + { + chatActivity.Text = result.AnswerSpan.Text; + } + // Create the attachment. var attachment = plCard.ToAttachment(); @@ -122,5 +136,45 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card return chatActivity; } + + /// + /// Get active learning suggestions card. + /// + /// Result to be dispalyed as prompts. + /// renderingchoice. + /// IMessageActivity. + public static IMessageActivity GetAnswerSpanCard(QueryResult result, int renderingOption) + { + if (result == null) + { + throw new ArgumentNullException(nameof(result)); + } + + var chatActivity = Activity.CreateMessageActivity(); + chatActivity.Text = result.Answer; + + // For content choice Precise only + if (renderingOption == 0) + { + chatActivity.Text = result.AnswerSpan.Text; + } + + var plCard = new HeroCard() + { + }; + + // For content choice Both Precise and Content + if (renderingOption == 1) + { + plCard.Text = result.Answer; + chatActivity.Text = result.AnswerSpan.Text; + var attachment = plCard.ToAttachment(); + + // Create the attachment. + chatActivity.Attachments.Add(attachment); + } + + return chatActivity; + } } } From a28e2c1c2b347faa6ad7ba31c38df2dd2dfe0e9f Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Fri, 22 May 2020 13:55:14 +0530 Subject: [PATCH 11/60] Tests for both and precise --- .../Utils/QnACardBuilder.cs | 10 +- .../QnAMakerContentBothDialog.cs | 56 ++++++ .../QnAMakerPreciseContentDialog.cs | 56 ++++++ .../QnAMakerTests.cs | 172 ++++++++++++++++++ .../TestData/QnaMaker.MRCEnable.json | 22 +++ 5 files changed, 311 insertions(+), 5 deletions(-) create mode 100644 tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs create mode 100644 tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs create mode 100644 tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker.MRCEnable.json diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index a40f8b55f3..9d19493ae4 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -83,7 +83,7 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, /// No match text. /// renderingchoice. /// IMessageActivity. - public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText, int renderingOption) + public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText, int renderingOption = 0) { if (result == null) { @@ -117,14 +117,14 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card }; // For content choice Both Precise and Content - if (renderingOption == 1) + if (renderingOption == 1 && result.AnswerSpan != null) { plCard.Text = result.Answer; chatActivity.Text = result.AnswerSpan.Text; } // For content choice Precise only - if (renderingOption == 0) + if (renderingOption == 0 && result.AnswerSpan != null) { chatActivity.Text = result.AnswerSpan.Text; } @@ -154,7 +154,7 @@ public static IMessageActivity GetAnswerSpanCard(QueryResult result, int renderi chatActivity.Text = result.Answer; // For content choice Precise only - if (renderingOption == 0) + if (renderingOption == 0 && result.AnswerSpan != null) { chatActivity.Text = result.AnswerSpan.Text; } @@ -164,7 +164,7 @@ public static IMessageActivity GetAnswerSpanCard(QueryResult result, int renderi }; // For content choice Both Precise and Content - if (renderingOption == 1) + if (renderingOption == 1 && result.AnswerSpan != null) { plCard.Text = result.Answer; chatActivity.Text = result.AnswerSpan.Text; diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs new file mode 100644 index 0000000000..8293d294fb --- /dev/null +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.AI.QnA; +using Microsoft.Bot.Builder.AI.QnA.Dialogs; +using Microsoft.Bot.Builder.Dialogs; +using Microsoft.Bot.Schema; + +namespace Microsoft.Bot.Builder.AI.Tests +{ + /// + /// QnAMaker action builder class. + /// + public class QnAMakerContentBothDialog : QnAMakerDialog + { + // Dialog Options parameters + public const string DefaultNoAnswer = "No QnAMaker answers found."; + public const string DefaultCardTitle = "Did you mean:"; + public const string DefaultCardNoMatchText = "None of the above."; + public const string DefaultCardNoMatchResponse = "Thanks for the feedback."; + + protected override Task GetQnAMakerOptionsAsync(DialogContext dc) + { + return Task.FromResult(new QnAMakerOptions + { + ScoreThreshold = DefaultThreshold, + Top = 3, + QnAId = 0, + RankerType = "Default", + IsTest = false, + EnablePreciseAnswer = true + }); + } + + protected async override Task GetQnAResponseOptionsAsync(DialogContext dc) + { + var noAnswer = (Activity)Activity.CreateMessageActivity(); + noAnswer.Text = DefaultNoAnswer; + + var cardNoMatchResponse = (Activity)MessageFactory.Text(DefaultCardNoMatchResponse); + + var responseOptions = new QnADialogResponseOptions + { + ActiveLearningCardTitle = DefaultCardTitle, + CardNoMatchText = DefaultCardNoMatchText, + NoAnswer = noAnswer, + CardNoMatchResponse = cardNoMatchResponse, + ContentChoice = QnADialogResponseOptions.Both + }; + + return responseOptions; + } + } +} diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs new file mode 100644 index 0000000000..90ab71f3cc --- /dev/null +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.AI.QnA; +using Microsoft.Bot.Builder.AI.QnA.Dialogs; +using Microsoft.Bot.Builder.Dialogs; +using Microsoft.Bot.Schema; + +namespace Microsoft.Bot.Builder.AI.Tests +{ + /// + /// QnAMaker action builder class. + /// + public class QnAMakerPreciseContentDialog : QnAMakerDialog + { + // Dialog Options parameters + public const string DefaultNoAnswer = "No QnAMaker answers found."; + public const string DefaultCardTitle = "Did you mean:"; + public const string DefaultCardNoMatchText = "None of the above."; + public const string DefaultCardNoMatchResponse = "Thanks for the feedback."; + + protected override Task GetQnAMakerOptionsAsync(DialogContext dc) + { + return Task.FromResult(new QnAMakerOptions + { + ScoreThreshold = DefaultThreshold, + Top = 3, + QnAId = 0, + RankerType = "Default", + IsTest = false, + EnablePreciseAnswer = true + }); + } + + protected async override Task GetQnAResponseOptionsAsync(DialogContext dc) + { + var noAnswer = (Activity)Activity.CreateMessageActivity(); + noAnswer.Text = DefaultNoAnswer; + + var cardNoMatchResponse = (Activity)MessageFactory.Text(DefaultCardNoMatchResponse); + + var responseOptions = new QnADialogResponseOptions + { + ActiveLearningCardTitle = DefaultCardTitle, + CardNoMatchText = DefaultCardNoMatchText, + NoAnswer = noAnswer, + CardNoMatchResponse = cardNoMatchResponse, + ContentChoice = QnADialogResponseOptions.PreciseAnswer + }; + + return responseOptions; + } + } +} diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index abfa4578e2..ca24163f51 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -46,10 +46,62 @@ public AdaptiveDialog QnAMakerAction_ActiveLearningDialogBase() .Respond(HttpStatusCode.NoContent, "application/json", "{ }"); mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"enablePreciseAnswer\":true}") + .Respond("application/json", GetResponse("QnaMaker.MRCEnable.json")); return CreateQnAMakerActionDialog(mockHttp); } + public AdaptiveDialog QnAMakerAction_PreciseDialogBase() + { + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); + mockHttp.When(HttpMethod.Post, GetTrainRequestUrl()) + .Respond(HttpStatusCode.NoContent, "application/json", "{ }"); + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":true}}") + .Respond("application/json", GetResponse("QnaMaker.MRCEnable.json")); + return CreateQnAMakerPreciseActionDialog(mockHttp); + } + + public AdaptiveDialog QnAMakerAction_ContentBothDialogBase() + { + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); + mockHttp.When(HttpMethod.Post, GetTrainRequestUrl()) + .Respond(HttpStatusCode.NoContent, "application/json", "{ }"); + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":true}}") + .Respond("application/json", GetResponse("QnaMaker.MRCEnable.json")); + return CreateQnAMakerContentBothDialog(mockHttp); + } + + [TestMethod] + public async Task QnAMaker_EnablePreciseAnswer() + { + var rootDialog = QnAMakerAction_PreciseDialogBase(); + + await CreateFlow(rootDialog) + .Send("Q13") + .AssertReply("some precise text") + .StartTestAsync(); + } + + [TestMethod] + public async Task QnAMaker_ContentBothAnswer() + { + var rootDialog = QnAMakerAction_ContentBothDialogBase(); + + await CreateFlow(rootDialog) + .Send("Q13") + .AssertReply("some precise text") + .StartTestAsync(); + } + [TestMethod] public async Task QnAMakerAction_ActiveLearningDialog_WithProperResponse() { @@ -1701,6 +1753,126 @@ private AdaptiveDialog CreateQnAMakerActionDialog(MockHttpMessageHandler mockHtt return rootDialog; } + private AdaptiveDialog CreateQnAMakerPreciseActionDialog(MockHttpMessageHandler mockHttp) + { + var client = new HttpClient(mockHttp); + + var noAnswerActivity = new ActivityTemplate("No match found, please as another question."); + var host = "https://dummy-hostname.azurewebsites.net/qnamaker"; + var knowlegeBaseId = "dummy-id"; + var endpointKey = "dummy-key"; + var activeLearningCardTitle = "QnAMaker Active Learning"; + + var outerDialog = new AdaptiveDialog("outer") + { + AutoEndDialog = false, + Triggers = new List() + { + new OnBeginDialog() + { + Actions = new List() + { + new QnAMakerPreciseContentDialog() + { + KnowledgeBaseId = knowlegeBaseId, + HostName = host, + EndpointKey = endpointKey, + HttpClient = client, + NoAnswer = noAnswerActivity, + ActiveLearningCardTitle = activeLearningCardTitle, + CardNoMatchText = "None of the above." + } + } + } + } + }; + + var rootDialog = new AdaptiveDialog("root") + { + Triggers = new List() + { + new OnBeginDialog() + { + Actions = new List() + { + new BeginDialog(outerDialog.Id) + } + }, + new OnDialogEvent() + { + Event = "UnhandledUnknownIntent", + Actions = new List() + { + new EditArray(), + new SendActivity("magenta") + } + } + } + }; + rootDialog.Dialogs.Add(outerDialog); + return rootDialog; + } + + private AdaptiveDialog CreateQnAMakerContentBothDialog(MockHttpMessageHandler mockHttp) + { + var client = new HttpClient(mockHttp); + + var noAnswerActivity = new ActivityTemplate("No match found, please as another question."); + var host = "https://dummy-hostname.azurewebsites.net/qnamaker"; + var knowlegeBaseId = "dummy-id"; + var endpointKey = "dummy-key"; + var activeLearningCardTitle = "QnAMaker Active Learning"; + + var outerDialog = new AdaptiveDialog("outer") + { + AutoEndDialog = false, + Triggers = new List() + { + new OnBeginDialog() + { + Actions = new List() + { + new QnAMakerContentBothDialog() + { + KnowledgeBaseId = knowlegeBaseId, + HostName = host, + EndpointKey = endpointKey, + HttpClient = client, + NoAnswer = noAnswerActivity, + ActiveLearningCardTitle = activeLearningCardTitle, + CardNoMatchText = "None of the above." + } + } + } + } + }; + + var rootDialog = new AdaptiveDialog("root") + { + Triggers = new List() + { + new OnBeginDialog() + { + Actions = new List() + { + new BeginDialog(outerDialog.Id) + } + }, + new OnDialogEvent() + { + Event = "UnhandledUnknownIntent", + Actions = new List() + { + new EditArray(), + new SendActivity("magenta") + } + } + } + }; + rootDialog.Dialogs.Add(outerDialog); + return rootDialog; + } + private string GetV2LegacyRequestUrl() => $"{_hostname}/v2.0/knowledgebases/{_knowledgeBaseId}/generateanswer"; private string GetV3LegacyRequestUrl() => $"{_hostname}/v3.0/knowledgebases/{_knowledgeBaseId}/generateanswer"; diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker.MRCEnable.json b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker.MRCEnable.json new file mode 100644 index 0000000000..78d94ab0a5 --- /dev/null +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker.MRCEnable.json @@ -0,0 +1,22 @@ +{ + "activeLearningEnabled": true, + "answers": [ + { + "questions": [ + "Q13" + ], + "answer": "A1", + "score": 80, + "id": 15, + "source": "Editorial", + "answerSpan": + { + "text": "some precise text", + "score": 0.22478714187291335, + "startIndex": 416, + "endIndex": 458 + } + } + ] + +} \ No newline at end of file From c244d078b1b5069526a76ac59a08e01950bdee9d Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Fri, 22 May 2020 14:56:21 +0530 Subject: [PATCH 12/60] Update GetQnAPromptsCard invocation in tests --- tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index ca24163f51..f02d8f2e27 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -172,7 +172,7 @@ public async Task QnAMakerAction_MultiTurnDialogBase_WithAnswer() var rootDialog = QnAMakerAction_MultiTurnDialogBase(); var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json"))); - var promptsActivity = QnACardBuilder.GetQnAPromptsCard(response.Answers[0], "None of the above."); + var promptsActivity = QnACardBuilder.GetQnAPromptsCard(response.Answers[0], "None of the above.", 0); var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); await CreateFlow(rootDialog) @@ -189,7 +189,7 @@ public async Task QnAMakerAction_MultiTurnDialogBase_WithNoAnswer() var rootDialog = QnAMakerAction_MultiTurnDialogBase(); var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json"))); - var promptsActivity = QnACardBuilder.GetQnAPromptsCard(response.Answers[0], "None of the above."); + var promptsActivity = QnACardBuilder.GetQnAPromptsCard(response.Answers[0], "None of the above.", 0); var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); await CreateFlow(rootDialog) From 9241f3de67b1dccb6cd8b97c610194da408e4fb2 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Fri, 22 May 2020 16:27:04 +0530 Subject: [PATCH 13/60] GetQnAPromptsContentCard method --- .../Dialogs/QnAMakerDialog.cs | 2 +- .../Utils/QnACardBuilder.cs | 21 ++++++++++++++----- .../QnAMakerTests.cs | 4 ++-- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 88db3c67a7..92225fb823 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -642,7 +642,7 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC } // Get multi-turn prompts card activity. - var message = QnACardBuilder.GetQnAPromptsCard(answer, dialogOptions.ResponseOptions.CardNoMatchText, contentChoice); + var message = QnACardBuilder.GetQnAPromptsContentCard(answer, dialogOptions.ResponseOptions.CardNoMatchText, contentChoice); await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false); return new DialogTurnResult(DialogTurnStatus.Waiting); diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index 9d19493ae4..d3297d3b6d 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -28,7 +28,7 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, throw new ArgumentNullException(nameof(suggestionsList)); } - if (cardTitle == null) + if (cardTitle == null) { throw new ArgumentNullException(nameof(cardTitle)); } @@ -80,10 +80,21 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, /// Get active learning suggestions card. /// /// Result to be dispalyed as prompts. + /// No match text. + /// IMessageActivity. + public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText) + { + return GetQnAPromptsContentCard(result, cardNoMatchText, 0); + } + + /// + /// Get active learning suggestions content card. + /// + /// Result to be dispalyed as prompts. /// No match text. /// renderingchoice. /// IMessageActivity. - public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText, int renderingOption = 0) + public static IMessageActivity GetQnAPromptsContentCard(QueryResult result, string cardNoMatchText, int renderingOption) { if (result == null) { @@ -135,7 +146,7 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card chatActivity.Attachments.Add(attachment); return chatActivity; - } + } /// /// Get active learning suggestions card. @@ -160,7 +171,7 @@ public static IMessageActivity GetAnswerSpanCard(QueryResult result, int renderi } var plCard = new HeroCard() - { + { }; // For content choice Both Precise and Content @@ -173,7 +184,7 @@ public static IMessageActivity GetAnswerSpanCard(QueryResult result, int renderi // Create the attachment. chatActivity.Attachments.Add(attachment); } - + return chatActivity; } } diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index f02d8f2e27..23b10dbad4 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -172,7 +172,7 @@ public async Task QnAMakerAction_MultiTurnDialogBase_WithAnswer() var rootDialog = QnAMakerAction_MultiTurnDialogBase(); var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json"))); - var promptsActivity = QnACardBuilder.GetQnAPromptsCard(response.Answers[0], "None of the above.", 0); + var promptsActivity = QnACardBuilder.GetQnAPromptsContentCard(response.Answers[0], "None of the above.", 0); var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); await CreateFlow(rootDialog) @@ -189,7 +189,7 @@ public async Task QnAMakerAction_MultiTurnDialogBase_WithNoAnswer() var rootDialog = QnAMakerAction_MultiTurnDialogBase(); var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json"))); - var promptsActivity = QnACardBuilder.GetQnAPromptsCard(response.Answers[0], "None of the above.", 0); + var promptsActivity = QnACardBuilder.GetQnAPromptsContentCard(response.Answers[0], "None of the above.", 0); var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); await CreateFlow(rootDialog) From 761ddd224f4b8c4fff040dc220fe1b3552dcea03 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Fri, 22 May 2020 20:04:26 +0530 Subject: [PATCH 14/60] Review comments --- .../QnAMakerOptions.cs | 2 +- .../Utils/GenerateAnswerUtils.cs | 20 ++++++++++++++----- .../QnAMakerTests.cs | 6 +++--- ...nable.json => QnaMaker.EnablePrecise.json} | 0 4 files changed, 19 insertions(+), 9 deletions(-) rename tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/{QnaMaker.MRCEnable.json => QnaMaker.EnablePrecise.json} (100%) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs index 68f86a736e..daf507d654 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs @@ -99,7 +99,7 @@ public QnAMakerOptions() /// /// To enable MRC. /// - [JsonProperty("enableMRC")] + [JsonProperty("enablePreciseAnswer")] public bool EnablePreciseAnswer { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs index cbf86dab8b..bb666698c0 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs @@ -142,7 +142,7 @@ private static void ValidateOptions(QnAMakerOptions options) if (options.RankerType == null) { options.RankerType = RankerTypes.DefaultRankerType; - } + } } /// @@ -184,8 +184,13 @@ private QnAMakerOptions HydrateOptions(QnAMakerOptions queryOptions) private async Task QueryQnaServiceAsync(Activity messageActivity, QnAMakerOptions options) { var requestUrl = $"{_endpoint.Host}/knowledgebases/{_endpoint.KnowledgeBaseId}/generateanswer"; - var answerSpanRequest = new AnswerSpanRequest(); - answerSpanRequest.Enable = options.EnablePreciseAnswer; + AnswerSpanRequest answerSpanRequest = null; + if (options.EnablePreciseAnswer) + { + answerSpanRequest = new AnswerSpanRequest(); + answerSpanRequest.Enable = options.EnablePreciseAnswer; + } + var jsonRequest = JsonConvert.SerializeObject( new { @@ -210,8 +215,13 @@ private async Task QueryQnaServiceAsync(Activity messageActivity, private async Task EmitTraceInfoAsync(ITurnContext turnContext, Activity messageActivity, QueryResult[] result, QnAMakerOptions options) { - var answerSpanRequest = new AnswerSpanRequest(); - answerSpanRequest.Enable = options.EnablePreciseAnswer; + AnswerSpanRequest answerSpanRequest = null; + if (options.EnablePreciseAnswer) + { + answerSpanRequest = new AnswerSpanRequest(); + answerSpanRequest.Enable = options.EnablePreciseAnswer; + } + var traceInfo = new QnAMakerTraceInfo { Message = (Activity)messageActivity, diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index 23b10dbad4..5bffd1a78a 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -47,7 +47,7 @@ public AdaptiveDialog QnAMakerAction_ActiveLearningDialogBase() mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"enablePreciseAnswer\":true}") - .Respond("application/json", GetResponse("QnaMaker.MRCEnable.json")); + .Respond("application/json", GetResponse("QnaMaker.EnablePrecise.json")); return CreateQnAMakerActionDialog(mockHttp); } @@ -62,7 +62,7 @@ public AdaptiveDialog QnAMakerAction_PreciseDialogBase() mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":true}}") - .Respond("application/json", GetResponse("QnaMaker.MRCEnable.json")); + .Respond("application/json", GetResponse("QnaMaker.EnablePrecise.json")); return CreateQnAMakerPreciseActionDialog(mockHttp); } @@ -76,7 +76,7 @@ public AdaptiveDialog QnAMakerAction_ContentBothDialogBase() mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":true}}") - .Respond("application/json", GetResponse("QnaMaker.MRCEnable.json")); + .Respond("application/json", GetResponse("QnaMaker.EnablePrecise.json")); return CreateQnAMakerContentBothDialog(mockHttp); } diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker.MRCEnable.json b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker.EnablePrecise.json similarity index 100% rename from tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker.MRCEnable.json rename to tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker.EnablePrecise.json From 75c01c93e3191debd10066cc930e0b99b7abe81d Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Fri, 22 May 2020 21:27:28 +0530 Subject: [PATCH 15/60] Request changes --- .../QnAMakerRecognizerTests.cs | 8 ++++---- .../QnAMakerTests.cs | 20 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs index 242a484707..907369fe07 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs @@ -59,16 +59,16 @@ public AdaptiveDialog QnAMakerRecognizer_DialogBase() { var mockHttp = new MockHttpMessageHandler(); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_ReturnsAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + .WithContent("{\"question\":\"QnaMaker_ReturnsAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_ReturnsNoAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + .WithContent("{\"question\":\"QnaMaker_ReturnsNoAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") .Respond("application/json", GetResponse("QnaMaker_ReturnsNoAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_TopNAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + .WithContent("{\"question\":\"QnaMaker_TopNAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_ReturnsAnswerWithIntent\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + .WithContent("{\"question\":\"QnaMaker_ReturnsAnswerWithIntent\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswerWithIntent.json")); return CreateQnAMakerActionDialog(mockHttp); diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index 5bffd1a78a..df32c7d5ed 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -39,12 +39,12 @@ public class QnAMakerTests public AdaptiveDialog QnAMakerAction_ActiveLearningDialogBase() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetTrainRequestUrl()) .Respond(HttpStatusCode.NoContent, "application/json", "{ }"); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"enablePreciseAnswer\":true}") .Respond("application/json", GetResponse("QnaMaker.EnablePrecise.json")); @@ -55,11 +55,11 @@ public AdaptiveDialog QnAMakerAction_ActiveLearningDialogBase() public AdaptiveDialog QnAMakerAction_PreciseDialogBase() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetTrainRequestUrl()) .Respond(HttpStatusCode.NoContent, "application/json", "{ }"); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":true}}") .Respond("application/json", GetResponse("QnaMaker.EnablePrecise.json")); @@ -69,11 +69,11 @@ public AdaptiveDialog QnAMakerAction_PreciseDialogBase() public AdaptiveDialog QnAMakerAction_ContentBothDialogBase() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetTrainRequestUrl()) .Respond(HttpStatusCode.NoContent, "application/json", "{ }"); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":true}}") .Respond("application/json", GetResponse("QnaMaker.EnablePrecise.json")); @@ -157,10 +157,10 @@ await CreateFlow(rootDialog) public AdaptiveDialog QnAMakerAction_MultiTurnDialogBase() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"I have issues related to KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"I have issues related to KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") .Respond("application/json", GetResponse("QnaMaker_ReturnAnswer_withPrompts.json")); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Accidently deleted KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":27,\"previousUserQuery\":\"\"},\"qnaId\":1,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Accidently deleted KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":27,\"previousUserQuery\":\"\"},\"qnaId\":1,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") .Respond("application/json", GetResponse("QnaMaker_ReturnAnswer_MultiTurnLevel1.json")); return CreateQnAMakerActionDialog(mockHttp); From 7bbf06ae2307f9c08c06c1d6c96f9ad7b9b3bcfb Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Sat, 23 May 2020 16:25:42 +0530 Subject: [PATCH 16/60] refactoring --- .../Dialogs/QnAMakerDialog.cs | 37 +----- .../{AnswerSpan.cs => AnswerSpanResponse.cs} | 2 +- .../Models/QueryResult.cs | 2 +- .../QnADialogResponseOptions.cs | 10 +- .../Utils/QnACardBuilder.cs | 111 +++++++----------- .../QnAMakerContentBothDialog.cs | 2 +- .../QnAMakerPreciseContentDialog.cs | 2 +- .../QnAMakerTests.cs | 4 +- 8 files changed, 51 insertions(+), 119 deletions(-) rename libraries/Microsoft.Bot.Builder.AI.QnA/Models/{AnswerSpan.cs => AnswerSpanResponse.cs} (96%) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 92225fb823..85b31f53c1 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -615,7 +615,6 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC if (answer.Context != null && answer.Context.Prompts.Count() > 0) { var previousContextData = ObjectPath.GetPathValue(stepContext.ActiveDialog.State, QnAContextData, new Dictionary()); - var previousQnAId = ObjectPath.GetPathValue(stepContext.ActiveDialog.State, PreviousQnAId, 0); foreach (var prompt in answer.Context.Prompts) { @@ -626,23 +625,8 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC ObjectPath.SetPathValue(stepContext.ActiveDialog.State, PreviousQnAId, answer.Id); ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions); - int contentChoice = -1; - - if (answer.AnswerSpan != null && !string.IsNullOrEmpty(answer.AnswerSpan.Text)) - { - if (dialogOptions.ResponseOptions.ContentChoice.Equals(QnADialogResponseOptions.PreciseAnswer)) - { - contentChoice = 0; - } - - if (dialogOptions.ResponseOptions.ContentChoice.Equals(QnADialogResponseOptions.Both)) - { - contentChoice = 1; - } - } - // Get multi-turn prompts card activity. - var message = QnACardBuilder.GetQnAPromptsContentCard(answer, dialogOptions.ResponseOptions.CardNoMatchText, contentChoice); + var message = QnACardBuilder.GetQnADefaultResponse(answer, dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly); await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false); return new DialogTurnResult(DialogTurnStatus.Waiting); @@ -690,24 +674,7 @@ private async Task DisplayQnAResultAsync(WaterfallStepContext // If response is present then show that response, else default answer. if (stepContext.Result is List response && response.Count > 0) { - var firstAnswer = response.First(); - var answer = firstAnswer.Answer; - int contentChoice = -1; - - if (firstAnswer.AnswerSpan != null && !string.IsNullOrEmpty(firstAnswer.AnswerSpan.Text)) - { - if (dialogOptions.ResponseOptions.ContentChoice.Equals(QnADialogResponseOptions.PreciseAnswer)) - { - contentChoice = 0; - } - - if (dialogOptions.ResponseOptions.ContentChoice.Equals(QnADialogResponseOptions.Both)) - { - contentChoice = 1; - } - } - - var message = QnACardBuilder.GetAnswerSpanCard(firstAnswer, contentChoice); + var message = QnACardBuilder.GetQnADefaultResponse(response.First(), dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly); await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false); } else diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs similarity index 96% rename from libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs rename to libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs index bc2de3d5c5..6900045b3f 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpan.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs @@ -5,7 +5,7 @@ namespace Microsoft.Bot.Builder.AI.QnA { - public class AnswerSpan + public class AnswerSpanResponse { /// /// Gets or sets the answer text. diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs index ea8d86a5ae..eecca1c126 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs @@ -84,6 +84,6 @@ public class QueryResult /// The answerspan value. /// [JsonProperty("answerSpan")] - public AnswerSpan AnswerSpan { get; set; } + public AnswerSpanResponse AnswerSpan { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs index d9eee18037..e69476c997 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs @@ -10,10 +10,6 @@ namespace Microsoft.Bot.Builder.AI.QnA /// public class QnADialogResponseOptions { - public const string PreciseAnswer = "PreciseAnswer"; - - public const string Both = "Both"; - /// /// Gets or sets get or set for Active learning card title. /// @@ -47,11 +43,11 @@ public class QnADialogResponseOptions public Activity CardNoMatchResponse { get; set; } /// - /// Gets or sets get or set for MRCAnswerSpanRenderingOption. + /// Gets or sets a value indicating whether DisplayPreciseAnswerOnly. /// /// - /// Get or set for Card no match MRCAnswerSpanRenderingOption. + /// Get or set for Card no match DisplayPreciseAnswerOnly. /// - public string ContentChoice { get; set; } = PreciseAnswer; + public bool DisplayPreciseAnswerOnly { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index d3297d3b6d..63d4b22275 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -77,111 +77,80 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, } /// - /// Get active learning suggestions card. + /// Get Card for MultiTurn scenario. (Can be deprected from 4.10.0 release of sdk). /// /// Result to be dispalyed as prompts. /// No match text. /// IMessageActivity. public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText) { - return GetQnAPromptsContentCard(result, cardNoMatchText, 0); + return GetQnADefaultResponse(result, true); } /// - /// Get active learning suggestions content card. + /// Get Card for MultiTurn scenario. /// /// Result to be dispalyed as prompts. - /// No match text. - /// renderingchoice. + /// renderingchoice. /// IMessageActivity. - public static IMessageActivity GetQnAPromptsContentCard(QueryResult result, string cardNoMatchText, int renderingOption) + public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool displayPreciseAnswerOnly) { if (result == null) { throw new ArgumentNullException(nameof(result)); } - if (cardNoMatchText == null) - { - throw new ArgumentNullException(nameof(cardNoMatchText)); - } - var chatActivity = Activity.CreateMessageActivity(); chatActivity.Text = result.Answer; - var buttonList = new List(); - - // Add all prompt - foreach (var prompt in result.Context.Prompts) - { - buttonList.Add( - new CardAction() - { - Value = prompt.DisplayText, - Type = "imBack", - Title = prompt.DisplayText, - }); - } - - var plCard = new HeroCard() + + List buttonList = null; + if (result?.Context?.Prompts != null && + result.Context.Prompts.Any()) { - Buttons = buttonList - }; + buttonList = new List(); - // For content choice Both Precise and Content - if (renderingOption == 1 && result.AnswerSpan != null) - { - plCard.Text = result.Answer; - chatActivity.Text = result.AnswerSpan.Text; + // Add all prompt + foreach (var prompt in result.Context.Prompts) + { + buttonList.Add( + new CardAction() + { + Value = prompt.DisplayText, + Type = "imBack", + Title = prompt.DisplayText, + }); + } } - // For content choice Precise only - if (renderingOption == 0 && result.AnswerSpan != null) + string heroCardText = null; + if (!string.IsNullOrWhiteSpace(result?.AnswerSpan?.Text)) { chatActivity.Text = result.AnswerSpan.Text; - } - - // Create the attachment. - var attachment = plCard.ToAttachment(); - - chatActivity.Attachments.Add(attachment); - - return chatActivity; - } - /// - /// Get active learning suggestions card. - /// - /// Result to be dispalyed as prompts. - /// renderingchoice. - /// IMessageActivity. - public static IMessageActivity GetAnswerSpanCard(QueryResult result, int renderingOption) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); + // For content choice Precise only + if (!displayPreciseAnswerOnly) + { + heroCardText = result.Answer; + } } - var chatActivity = Activity.CreateMessageActivity(); - chatActivity.Text = result.Answer; - - // For content choice Precise only - if (renderingOption == 0 && result.AnswerSpan != null) + if (buttonList != null || !string.IsNullOrWhiteSpace(heroCardText)) { - chatActivity.Text = result.AnswerSpan.Text; - } + var plCard = new HeroCard(); - var plCard = new HeroCard() - { - }; + if (buttonList != null) + { + plCard.Buttons = buttonList; + } - // For content choice Both Precise and Content - if (renderingOption == 1 && result.AnswerSpan != null) - { - plCard.Text = result.Answer; - chatActivity.Text = result.AnswerSpan.Text; - var attachment = plCard.ToAttachment(); + if (!string.IsNullOrWhiteSpace(heroCardText)) + { + plCard.Text = heroCardText; + } // Create the attachment. + var attachment = plCard.ToAttachment(); + chatActivity.Attachments.Add(attachment); } diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs index 8293d294fb..84cf4257e7 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs @@ -47,7 +47,7 @@ protected async override Task GetQnAResponseOptionsAsy CardNoMatchText = DefaultCardNoMatchText, NoAnswer = noAnswer, CardNoMatchResponse = cardNoMatchResponse, - ContentChoice = QnADialogResponseOptions.Both + DisplayPreciseAnswerOnly = false }; return responseOptions; diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs index 90ab71f3cc..bbcf7805a3 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs @@ -47,7 +47,7 @@ protected async override Task GetQnAResponseOptionsAsy CardNoMatchText = DefaultCardNoMatchText, NoAnswer = noAnswer, CardNoMatchResponse = cardNoMatchResponse, - ContentChoice = QnADialogResponseOptions.PreciseAnswer + DisplayPreciseAnswerOnly = true }; return responseOptions; diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index df32c7d5ed..03efeb1230 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -172,7 +172,7 @@ public async Task QnAMakerAction_MultiTurnDialogBase_WithAnswer() var rootDialog = QnAMakerAction_MultiTurnDialogBase(); var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json"))); - var promptsActivity = QnACardBuilder.GetQnAPromptsContentCard(response.Answers[0], "None of the above.", 0); + var promptsActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true); var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); await CreateFlow(rootDialog) @@ -189,7 +189,7 @@ public async Task QnAMakerAction_MultiTurnDialogBase_WithNoAnswer() var rootDialog = QnAMakerAction_MultiTurnDialogBase(); var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json"))); - var promptsActivity = QnACardBuilder.GetQnAPromptsContentCard(response.Answers[0], "None of the above.", 0); + var promptsActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true); var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); await CreateFlow(rootDialog) From 7d27031b2aaa03a5764d600d282f9e7ed3ff45d8 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Sun, 24 May 2020 14:13:17 +0530 Subject: [PATCH 17/60] Refactoring Tests --- .../Dialogs/QnAMakerDialog.cs | 26 ++- .../QnADialogResponseOptions.cs | 2 +- .../QnAMakerOptions.cs | 4 +- .../QnAMakerCardEqualityComparer.cs | 9 + .../QnAMakerContentBothDialog.cs | 56 ------ .../QnAMakerPreciseContentDialog.cs | 56 ------ .../QnAMakerTests.cs | 189 +++--------------- ...Maker_ReturnAnswersWithPreciseAnswer.json} | 0 8 files changed, 68 insertions(+), 274 deletions(-) delete mode 100644 tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs delete mode 100644 tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs rename tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/{QnaMaker.EnablePrecise.json => QnaMaker_ReturnAnswersWithPreciseAnswer.json} (100%) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 85b31f53c1..c9bbb3b2f4 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -290,6 +290,24 @@ public QnAMakerDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNu [JsonProperty("rankerType")] public StringExpression RankerType { get; set; } = new StringExpression(RankerTypes.DefaultRankerType); + /// + /// Gets or sets a value indicating whether gets or sets enablePreciseAnswer. + /// + /// + /// A value indicating whether to enable Precise Answer or not. + /// + [JsonProperty("enablePreciseAnswer")] + public bool EnablePreciseAnswer { get; set; } + + /// + /// Gets or sets a value indicating whether gets or sets displayPreciseAnswerOnly. + /// + /// + /// A value indicating whether to display Precise Answer Only or Both. + /// + [JsonProperty("displayPreciseAnswerOnly")] + public bool DisplayPreciseAnswerOnly { get; set; } + /// /// Called when the dialog is started and pushed onto the dialog stack. /// @@ -427,8 +445,9 @@ protected virtual Task GetQnAMakerOptionsAsync(DialogContext dc Context = new QnARequestContext(), QnAId = 0, RankerType = this.RankerType?.GetValue(dc.State), - IsTest = this.IsTest - }); + IsTest = this.IsTest, + EnablePreciseAnswer = this.EnablePreciseAnswer + }); } /// @@ -444,7 +463,8 @@ protected async virtual Task GetQnAResponseOptionsAsyn NoAnswer = await this.NoAnswer.BindAsync(dc, dc.State).ConfigureAwait(false), ActiveLearningCardTitle = this.ActiveLearningCardTitle?.GetValue(dc.State) ?? DefaultCardTitle, CardNoMatchText = this.CardNoMatchText?.GetValue(dc.State) ?? DefaultCardNoMatchText, - CardNoMatchResponse = await this.CardNoMatchResponse.BindAsync(dc).ConfigureAwait(false) + CardNoMatchResponse = await this.CardNoMatchResponse.BindAsync(dc).ConfigureAwait(false), + DisplayPreciseAnswerOnly = this.DisplayPreciseAnswerOnly }; } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs index e69476c997..d5727e71e0 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs @@ -46,7 +46,7 @@ public class QnADialogResponseOptions /// Gets or sets a value indicating whether DisplayPreciseAnswerOnly. /// /// - /// Get or set for Card no match DisplayPreciseAnswerOnly. + /// Get or set whether to display Precise Answer Only or Both. /// public bool DisplayPreciseAnswerOnly { get; set; } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs index daf507d654..0bcd05d043 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs @@ -94,10 +94,10 @@ public QnAMakerOptions() public string RankerType { get; set; } /// - /// Gets or sets a value indicating whether MRCEnable of the previous turn. + /// Gets or sets a value indicating whether enable Precise Answer. /// /// - /// To enable MRC. + /// To enable Precise Answer or not. /// [JsonProperty("enablePreciseAnswer")] public bool EnablePreciseAnswer { get; set; } diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs index 20e411a5a7..7c35754442 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs @@ -39,6 +39,15 @@ public bool Equals(IActivity x, IActivity y) } } + // Check for text + if (activity1.Text != null && activity2.Text != null) + { + if (activity1.Attachments.Count != activity2.Attachments.Count) + { + return false; + } + } + return true; } diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs deleted file mode 100644 index 84cf4257e7..0000000000 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerContentBothDialog.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System.Threading.Tasks; -using Microsoft.Bot.Builder; -using Microsoft.Bot.Builder.AI.QnA; -using Microsoft.Bot.Builder.AI.QnA.Dialogs; -using Microsoft.Bot.Builder.Dialogs; -using Microsoft.Bot.Schema; - -namespace Microsoft.Bot.Builder.AI.Tests -{ - /// - /// QnAMaker action builder class. - /// - public class QnAMakerContentBothDialog : QnAMakerDialog - { - // Dialog Options parameters - public const string DefaultNoAnswer = "No QnAMaker answers found."; - public const string DefaultCardTitle = "Did you mean:"; - public const string DefaultCardNoMatchText = "None of the above."; - public const string DefaultCardNoMatchResponse = "Thanks for the feedback."; - - protected override Task GetQnAMakerOptionsAsync(DialogContext dc) - { - return Task.FromResult(new QnAMakerOptions - { - ScoreThreshold = DefaultThreshold, - Top = 3, - QnAId = 0, - RankerType = "Default", - IsTest = false, - EnablePreciseAnswer = true - }); - } - - protected async override Task GetQnAResponseOptionsAsync(DialogContext dc) - { - var noAnswer = (Activity)Activity.CreateMessageActivity(); - noAnswer.Text = DefaultNoAnswer; - - var cardNoMatchResponse = (Activity)MessageFactory.Text(DefaultCardNoMatchResponse); - - var responseOptions = new QnADialogResponseOptions - { - ActiveLearningCardTitle = DefaultCardTitle, - CardNoMatchText = DefaultCardNoMatchText, - NoAnswer = noAnswer, - CardNoMatchResponse = cardNoMatchResponse, - DisplayPreciseAnswerOnly = false - }; - - return responseOptions; - } - } -} diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs deleted file mode 100644 index bbcf7805a3..0000000000 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerPreciseContentDialog.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System.Threading.Tasks; -using Microsoft.Bot.Builder; -using Microsoft.Bot.Builder.AI.QnA; -using Microsoft.Bot.Builder.AI.QnA.Dialogs; -using Microsoft.Bot.Builder.Dialogs; -using Microsoft.Bot.Schema; - -namespace Microsoft.Bot.Builder.AI.Tests -{ - /// - /// QnAMaker action builder class. - /// - public class QnAMakerPreciseContentDialog : QnAMakerDialog - { - // Dialog Options parameters - public const string DefaultNoAnswer = "No QnAMaker answers found."; - public const string DefaultCardTitle = "Did you mean:"; - public const string DefaultCardNoMatchText = "None of the above."; - public const string DefaultCardNoMatchResponse = "Thanks for the feedback."; - - protected override Task GetQnAMakerOptionsAsync(DialogContext dc) - { - return Task.FromResult(new QnAMakerOptions - { - ScoreThreshold = DefaultThreshold, - Top = 3, - QnAId = 0, - RankerType = "Default", - IsTest = false, - EnablePreciseAnswer = true - }); - } - - protected async override Task GetQnAResponseOptionsAsync(DialogContext dc) - { - var noAnswer = (Activity)Activity.CreateMessageActivity(); - noAnswer.Text = DefaultNoAnswer; - - var cardNoMatchResponse = (Activity)MessageFactory.Text(DefaultCardNoMatchResponse); - - var responseOptions = new QnADialogResponseOptions - { - ActiveLearningCardTitle = DefaultCardTitle, - CardNoMatchText = DefaultCardNoMatchText, - NoAnswer = noAnswer, - CardNoMatchResponse = cardNoMatchResponse, - DisplayPreciseAnswerOnly = true - }; - - return responseOptions; - } - } -} diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index 03efeb1230..93dfa464b4 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -45,61 +45,56 @@ public AdaptiveDialog QnAMakerAction_ActiveLearningDialogBase() mockHttp.When(HttpMethod.Post, GetTrainRequestUrl()) .Respond(HttpStatusCode.NoContent, "application/json", "{ }"); mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") - .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"enablePreciseAnswer\":true}") - .Respond("application/json", GetResponse("QnaMaker.EnablePrecise.json")); - + .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); return CreateQnAMakerActionDialog(mockHttp); } - public AdaptiveDialog QnAMakerAction_PreciseDialogBase() + public AdaptiveDialog QnAMakerAction_PreciseDialogBase(bool displayPreciseAnswerOnly) { - var mockHttp = new MockHttpMessageHandler(); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") - .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); - mockHttp.When(HttpMethod.Post, GetTrainRequestUrl()) - .Respond(HttpStatusCode.NoContent, "application/json", "{ }"); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") - .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":true}}") - .Respond("application/json", GetResponse("QnaMaker.EnablePrecise.json")); - return CreateQnAMakerPreciseActionDialog(mockHttp); - } - - public AdaptiveDialog QnAMakerAction_ContentBothDialogBase() - { - var mockHttp = new MockHttpMessageHandler(); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") - .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); - mockHttp.When(HttpMethod.Post, GetTrainRequestUrl()) - .Respond(HttpStatusCode.NoContent, "application/json", "{ }"); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\"}") - .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q13\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":true}}") - .Respond("application/json", GetResponse("QnaMaker.EnablePrecise.json")); - return CreateQnAMakerContentBothDialog(mockHttp); + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"PreciseAnswerQuestion\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":true}}") + .Respond("application/json", GetResponse("QnaMaker_ReturnAnswersWithPreciseAnswer.json")); + return CreateQnAMakerActionDialog(mockHttp, true, displayPreciseAnswerOnly); } [TestMethod] - public async Task QnAMaker_EnablePreciseAnswer() + public async Task QnaMaker_ReturnAnswer_WithDisplayPreciseAnswerOnly() { - var rootDialog = QnAMakerAction_PreciseDialogBase(); + var rootDialog = QnAMakerAction_PreciseDialogBase(true); await CreateFlow(rootDialog) - .Send("Q13") + .Send("PreciseAnswerQuestion") .AssertReply("some precise text") .StartTestAsync(); + + var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswersWithPreciseAnswer.json"))); + var preciseAnswerActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true); + var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); + + await CreateFlow(rootDialog) + .Send("PreciseAnswerQuestion") + .AssertReply(preciseAnswerActivity, equalityComparer: qnAMakerCardEqualityComparer) + .StartTestAsync(); } [TestMethod] - public async Task QnAMaker_ContentBothAnswer() + public async Task QnAMaker_ReturnAnswer_WithDisplayRegularAndPreciseAnswers() { - var rootDialog = QnAMakerAction_ContentBothDialogBase(); + var rootDialog = QnAMakerAction_PreciseDialogBase(false); await CreateFlow(rootDialog) - .Send("Q13") + .Send("PreciseAnswerQuestion") .AssertReply("some precise text") .StartTestAsync(); + + var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswersWithPreciseAnswer.json"))); + var preciseAnswerActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], false); + var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); + + await CreateFlow(rootDialog) + .Send("PreciseAnswerQuestion") + .AssertReply(preciseAnswerActivity, equalityComparer: qnAMakerCardEqualityComparer) + .StartTestAsync(); } [TestMethod] @@ -1693,7 +1688,7 @@ public override async Task ResumeDialogAsync(DialogContext dc, } } - private AdaptiveDialog CreateQnAMakerActionDialog(MockHttpMessageHandler mockHttp) + private AdaptiveDialog CreateQnAMakerActionDialog(MockHttpMessageHandler mockHttp, bool enablePreciseAnswer = false, bool displayPreciseAnswerOnly = false) { var client = new HttpClient(mockHttp); @@ -1721,126 +1716,8 @@ private AdaptiveDialog CreateQnAMakerActionDialog(MockHttpMessageHandler mockHtt NoAnswer = noAnswerActivity, ActiveLearningCardTitle = activeLearningCardTitle, CardNoMatchText = "None of the above.", - } - } - } - } - }; - - var rootDialog = new AdaptiveDialog("root") - { - Triggers = new List() - { - new OnBeginDialog() - { - Actions = new List() - { - new BeginDialog(outerDialog.Id) - } - }, - new OnDialogEvent() - { - Event = "UnhandledUnknownIntent", - Actions = new List() - { - new EditArray(), - new SendActivity("magenta") - } - } - } - }; - rootDialog.Dialogs.Add(outerDialog); - return rootDialog; - } - - private AdaptiveDialog CreateQnAMakerPreciseActionDialog(MockHttpMessageHandler mockHttp) - { - var client = new HttpClient(mockHttp); - - var noAnswerActivity = new ActivityTemplate("No match found, please as another question."); - var host = "https://dummy-hostname.azurewebsites.net/qnamaker"; - var knowlegeBaseId = "dummy-id"; - var endpointKey = "dummy-key"; - var activeLearningCardTitle = "QnAMaker Active Learning"; - - var outerDialog = new AdaptiveDialog("outer") - { - AutoEndDialog = false, - Triggers = new List() - { - new OnBeginDialog() - { - Actions = new List() - { - new QnAMakerPreciseContentDialog() - { - KnowledgeBaseId = knowlegeBaseId, - HostName = host, - EndpointKey = endpointKey, - HttpClient = client, - NoAnswer = noAnswerActivity, - ActiveLearningCardTitle = activeLearningCardTitle, - CardNoMatchText = "None of the above." - } - } - } - } - }; - - var rootDialog = new AdaptiveDialog("root") - { - Triggers = new List() - { - new OnBeginDialog() - { - Actions = new List() - { - new BeginDialog(outerDialog.Id) - } - }, - new OnDialogEvent() - { - Event = "UnhandledUnknownIntent", - Actions = new List() - { - new EditArray(), - new SendActivity("magenta") - } - } - } - }; - rootDialog.Dialogs.Add(outerDialog); - return rootDialog; - } - - private AdaptiveDialog CreateQnAMakerContentBothDialog(MockHttpMessageHandler mockHttp) - { - var client = new HttpClient(mockHttp); - - var noAnswerActivity = new ActivityTemplate("No match found, please as another question."); - var host = "https://dummy-hostname.azurewebsites.net/qnamaker"; - var knowlegeBaseId = "dummy-id"; - var endpointKey = "dummy-key"; - var activeLearningCardTitle = "QnAMaker Active Learning"; - - var outerDialog = new AdaptiveDialog("outer") - { - AutoEndDialog = false, - Triggers = new List() - { - new OnBeginDialog() - { - Actions = new List() - { - new QnAMakerContentBothDialog() - { - KnowledgeBaseId = knowlegeBaseId, - HostName = host, - EndpointKey = endpointKey, - HttpClient = client, - NoAnswer = noAnswerActivity, - ActiveLearningCardTitle = activeLearningCardTitle, - CardNoMatchText = "None of the above." + EnablePreciseAnswer = enablePreciseAnswer, + DisplayPreciseAnswerOnly = displayPreciseAnswerOnly } } } diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker.EnablePrecise.json b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker_ReturnAnswersWithPreciseAnswer.json similarity index 100% rename from tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker.EnablePrecise.json rename to tests/Microsoft.Bot.Builder.AI.QnA.Tests/TestData/QnaMaker_ReturnAnswersWithPreciseAnswer.json From d1a4fb4228636e580c94a34d83772f3755f60686 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Mon, 25 May 2020 18:05:45 +0530 Subject: [PATCH 18/60] Tests refactoring for comments --- .../Utils/QnACardBuilder.cs | 2 +- .../QnAMakerCardEqualityComparer.cs | 15 +++--- .../QnAMakerTests.cs | 54 ++++++++----------- 3 files changed, 29 insertions(+), 42 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index 63d4b22275..7a204c650b 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -88,7 +88,7 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card } /// - /// Get Card for MultiTurn scenario. + /// Get Card for Default QnA Maker scenario. /// /// Result to be dispalyed as prompts. /// renderingchoice. diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs index 7c35754442..8c1c66d4b4 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs @@ -30,17 +30,14 @@ public bool Equals(IActivity x, IActivity y) return false; } - // Check for attachments - if (activity1.Attachments != null && activity2.Attachments != null) + if ((activity1.Attachments == null && activity2.Attachments != null) || + (activity1.Attachments != null && activity2.Attachments == null)) { - if (activity1.Attachments.Count != activity2.Attachments.Count) - { - return false; - } + return false; } - // Check for text - if (activity1.Text != null && activity2.Text != null) + // Check for attachments + if (activity1.Attachments != null && activity2.Attachments != null) { if (activity1.Attachments.Count != activity2.Attachments.Count) { @@ -48,7 +45,7 @@ public bool Equals(IActivity x, IActivity y) } } - return true; + return string.Equals(activity1.Text, activity2.Text); } public int GetHashCode(IActivity obj) diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index 93dfa464b4..e2e99e405e 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -49,51 +49,41 @@ public AdaptiveDialog QnAMakerAction_ActiveLearningDialogBase() return CreateQnAMakerActionDialog(mockHttp); } - public AdaptiveDialog QnAMakerAction_PreciseDialogBase(bool displayPreciseAnswerOnly) - { - var mockHttp = new MockHttpMessageHandler(); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"PreciseAnswerQuestion\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":true}}") - .Respond("application/json", GetResponse("QnaMaker_ReturnAnswersWithPreciseAnswer.json")); - return CreateQnAMakerActionDialog(mockHttp, true, displayPreciseAnswerOnly); - } - [TestMethod] public async Task QnaMaker_ReturnAnswer_WithDisplayPreciseAnswerOnly() { - var rootDialog = QnAMakerAction_PreciseDialogBase(true); - - await CreateFlow(rootDialog) - .Send("PreciseAnswerQuestion") - .AssertReply("some precise text") - .StartTestAsync(); - - var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswersWithPreciseAnswer.json"))); - var preciseAnswerActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true); - var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); - - await CreateFlow(rootDialog) - .Send("PreciseAnswerQuestion") - .AssertReply(preciseAnswerActivity, equalityComparer: qnAMakerCardEqualityComparer) - .StartTestAsync(); + await QnAMaker_ReturnAnswer_PreciseAnswersValidate(true); } [TestMethod] public async Task QnAMaker_ReturnAnswer_WithDisplayRegularAndPreciseAnswers() { - var rootDialog = QnAMakerAction_PreciseDialogBase(false); + await QnAMaker_ReturnAnswer_PreciseAnswersValidate(false); + } - await CreateFlow(rootDialog) - .Send("PreciseAnswerQuestion") - .AssertReply("some precise text") - .StartTestAsync(); + public async Task QnAMaker_ReturnAnswer_PreciseAnswersValidate(bool displayPreciseAnswerOnly) + { + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"PreciseAnswerQuestion\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":true}}") + .Respond("application/json", GetResponse("QnaMaker_ReturnAnswersWithPreciseAnswer.json")); + var rootDialog = CreateQnAMakerActionDialog(mockHttp, true, displayPreciseAnswerOnly); var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswersWithPreciseAnswer.json"))); - var preciseAnswerActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], false); - var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); + var queryResult = response.Answers[0]; + + var preciseAnswerActivity = Activity.CreateMessageActivity(); + preciseAnswerActivity.Text = queryResult.AnswerSpan.Text; + + if (!displayPreciseAnswerOnly) + { + var plCard = new HeroCard(); + plCard.Text = queryResult.Answer; + preciseAnswerActivity.Attachments.Add(plCard.ToAttachment()); + } await CreateFlow(rootDialog) .Send("PreciseAnswerQuestion") - .AssertReply(preciseAnswerActivity, equalityComparer: qnAMakerCardEqualityComparer) + .AssertReply(preciseAnswerActivity, new QnAMakerCardEqualityComparer()) .StartTestAsync(); } @@ -1696,7 +1686,7 @@ private AdaptiveDialog CreateQnAMakerActionDialog(MockHttpMessageHandler mockHtt var host = "https://dummy-hostname.azurewebsites.net/qnamaker"; var knowlegeBaseId = "dummy-id"; var endpointKey = "dummy-key"; - var activeLearningCardTitle = "QnAMaker Active Learning"; + var activeLearningCardTitle = "Did you mean:"; var outerDialog = new AdaptiveDialog("outer") { From 84233edce662fd40d443074dd57304925576a58d Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Wed, 27 May 2020 04:39:31 +0530 Subject: [PATCH 19/60] Added Copyright headers --- libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index 8eea8391a8..b2dfb76334 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using System.Collections.Generic; using System.Text; using Newtonsoft.Json; From 55f3e2a1c89c1a61f91a1e9e467f8ee8cd394513 Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Wed, 27 May 2020 04:41:16 +0530 Subject: [PATCH 20/60] Modified comment text for review comment. --- .../Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index c9bbb3b2f4..2e1bb98f82 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -291,7 +291,7 @@ public QnAMakerDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNu public StringExpression RankerType { get; set; } = new StringExpression(RankerTypes.DefaultRankerType); /// - /// Gets or sets a value indicating whether gets or sets enablePreciseAnswer. + /// Gets or sets a value indicating whether to enable PreciseAnswer Generation. /// /// /// A value indicating whether to enable Precise Answer or not. From c556fc1d3f31499ed74f1dd44497e4fe01e4e6c2 Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Wed, 27 May 2020 04:44:11 +0530 Subject: [PATCH 21/60] Update QnAMakerDialog.cs --- .../Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 2e1bb98f82..ca059efa5d 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -294,7 +294,7 @@ public QnAMakerDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNu /// Gets or sets a value indicating whether to enable PreciseAnswer Generation. /// /// - /// A value indicating whether to enable Precise Answer or not. + /// A value indicating whether to enable Precise Answer Feature of QnAMaker Dynamic Answer Generation or not. /// [JsonProperty("enablePreciseAnswer")] public bool EnablePreciseAnswer { get; set; } From 2074646509c5586db13e1b01ef4a88101ce37055 Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Wed, 27 May 2020 04:46:10 +0530 Subject: [PATCH 22/60] document text modified. --- .../Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index ca059efa5d..d6379d7e3e 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -303,7 +303,7 @@ public QnAMakerDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNu /// Gets or sets a value indicating whether gets or sets displayPreciseAnswerOnly. /// /// - /// A value indicating whether to display Precise Answer Only or Both. + /// A value indicating whether to display Precise Answer Only or Both Precise Answer and Source Content from which answer is obtained. /// [JsonProperty("displayPreciseAnswerOnly")] public bool DisplayPreciseAnswerOnly { get; set; } From e97cd513279f63174107ce0cd00b006f6df0e4da Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Wed, 27 May 2020 06:12:45 +0530 Subject: [PATCH 23/60] Copy right header formatting --- .../Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs index 6900045b3f..b55ebcc483 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using Newtonsoft.Json; namespace Microsoft.Bot.Builder.AI.QnA From a5cfa1cd5eb71f4390589c8a6f1c0a6dfff87b0a Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Wed, 27 May 2020 22:43:28 +0530 Subject: [PATCH 24/60] Remove unused import --- .../Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs index b55ebcc483..6900045b3f 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; using Newtonsoft.Json; namespace Microsoft.Bot.Builder.AI.QnA From 09c5372a14849d8ec6c8e348d66cccf9fa672753 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Thu, 28 May 2020 09:45:32 +0530 Subject: [PATCH 25/60] Revert "Added Copyright headers" This reverts commit 84233edce662fd40d443074dd57304925576a58d. --- libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index b2dfb76334..8eea8391a8 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -1,7 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; +using System; using System.Collections.Generic; using System.Text; using Newtonsoft.Json; From a19c8d486fbf1bfce5d166b4ba8bbaaa9dbdc739 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Thu, 28 May 2020 09:48:41 +0530 Subject: [PATCH 26/60] Copyright header --- libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index 8eea8391a8..fc5f368214 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -1,6 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using Newtonsoft.Json; namespace Microsoft.Bot.Builder.AI.QnA From d0f51b5be5573afecd268961b082269310323303 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Thu, 28 May 2020 10:31:23 +0530 Subject: [PATCH 27/60] Comment modified for grammar and clarity --- libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index 7a204c650b..b64fb954aa 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -127,7 +127,7 @@ public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool di { chatActivity.Text = result.AnswerSpan.Text; - // For content choice Precise only + // When the configuration is set to display precise answer if (!displayPreciseAnswerOnly) { heroCardText = result.Answer; From 8b7aa4add73d378b23f7d4419ca0ef6627e2ae26 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Tue, 2 Jun 2020 22:33:37 +0530 Subject: [PATCH 28/60] Review comments --- .../AnswerSpanRequest.cs | 4 ++-- .../Dialogs/QnAMakerDialog.cs | 8 ++++---- .../QnAMakerRecognizer.cs | 7 +++++-- .../Utils/GenerateAnswerUtils.cs | 3 +-- .../Utils/QnACardBuilder.cs | 17 ++++++++++------- .../QnAMakerTests.cs | 4 ++-- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index fc5f368214..dbdcb83528 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -8,10 +8,10 @@ namespace Microsoft.Bot.Builder.AI.QnA public class AnswerSpanRequest { /// - /// Gets or sets a value indicating whether gets or sets the enablet. + /// Gets or sets a value indicating whether to enable PreciseAnswer generation or not. /// /// - /// The answer text. + /// Choice whether to generate precise answer or not. /// [JsonProperty("enable")] public bool Enable { get; set; } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index d6379d7e3e..4f78311448 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -456,7 +456,7 @@ protected virtual Task GetQnAMakerOptionsAsync(DialogContext dc /// The for the current turn of conversation. /// A representing the asynchronous operation. /// If the task is successful, the result contains the response options to use. - protected async virtual Task GetQnAResponseOptionsAsync(DialogContext dc) + protected virtual async Task GetQnAResponseOptionsAsync(DialogContext dc) { return new QnADialogResponseOptions { @@ -632,7 +632,7 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC var answer = response.First(); - if (answer.Context != null && answer.Context.Prompts.Count() > 0) + if (!(answer.Context == null || answer.Context.Prompts.Count() == 0)) { var previousContextData = ObjectPath.GetPathValue(stepContext.ActiveDialog.State, QnAContextData, new Dictionary()); @@ -646,7 +646,7 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions); // Get multi-turn prompts card activity. - var message = QnACardBuilder.GetQnADefaultResponse(answer, dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly); + var message = QnACardBuilder.GetQnADefaultResponse(answer, dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly, cancellationToken); await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false); return new DialogTurnResult(DialogTurnStatus.Waiting); @@ -694,7 +694,7 @@ private async Task DisplayQnAResultAsync(WaterfallStepContext // If response is present then show that response, else default answer. if (stepContext.Result is List response && response.Count > 0) { - var message = QnACardBuilder.GetQnADefaultResponse(response.First(), dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly); + var message = QnACardBuilder.GetQnADefaultResponse(response.First(), dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly, cancellationToken); await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false); } else diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs index 5696a494a5..dc7ed47fe8 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs @@ -140,6 +140,8 @@ public QnAMakerRecognizer() [JsonProperty("logPersonalInformation")] public BoolExpression LogPersonalInformation { get; set; } = "=settings.telemetry.logPersonalInformation"; + public bool EnablePreciseAnswer { get; set; } + public override async Task RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken, Dictionary telemetryProperties = null, Dictionary telemetryMetrics = null) { // Identify matched intents @@ -180,7 +182,8 @@ public override async Task RecognizeAsync(DialogContext dialog Top = this.Top.GetValue(dialogContext.State), QnAId = this.QnAId.GetValue(dialogContext.State), RankerType = this.RankerType.GetValue(dialogContext.State), - IsTest = this.IsTest + IsTest = this.IsTest, + EnablePreciseAnswer = this.EnablePreciseAnswer }, null).ConfigureAwait(false); @@ -191,7 +194,7 @@ public override async Task RecognizeAsync(DialogContext dialog { if ((topAnswer == null) || (answer.Score > topAnswer.Score)) { - topAnswer = answer; + topAnswer = answer; } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs index bb666698c0..7829ff2e8d 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs @@ -187,8 +187,7 @@ private async Task QueryQnaServiceAsync(Activity messageActivity, AnswerSpanRequest answerSpanRequest = null; if (options.EnablePreciseAnswer) { - answerSpanRequest = new AnswerSpanRequest(); - answerSpanRequest.Enable = options.EnablePreciseAnswer; + answerSpanRequest = new AnswerSpanRequest { Enable = options.EnablePreciseAnswer }; } var jsonRequest = JsonConvert.SerializeObject( diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index b64fb954aa..9aaf57269e 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Microsoft.Bot.Schema; @@ -77,23 +78,25 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, } /// - /// Get Card for MultiTurn scenario. (Can be deprected from 4.10.0 release of sdk). + /// Get Card for MultiTurn scenario. (Can be deprecated from 4.10.0 release of sdk). /// - /// Result to be dispalyed as prompts. - /// No match text. + /// Result to be displayed as prompts. + /// No match text. + /// cancellationToken. /// IMessageActivity. - public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText) + public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText, CancellationToken cancellationToken) { - return GetQnADefaultResponse(result, true); + return GetQnADefaultResponse(result, true, cancellationToken); } /// /// Get Card for Default QnA Maker scenario. /// - /// Result to be dispalyed as prompts. + /// Result to be displayed as prompts. /// renderingchoice. + /// cancellationToken. /// IMessageActivity. - public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool displayPreciseAnswerOnly) + public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool displayPreciseAnswerOnly, CancellationToken cancellationToken) { if (result == null) { diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index e2e99e405e..9d02d20778 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -157,7 +157,7 @@ public async Task QnAMakerAction_MultiTurnDialogBase_WithAnswer() var rootDialog = QnAMakerAction_MultiTurnDialogBase(); var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json"))); - var promptsActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true); + var promptsActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true, CancellationToken.None); var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); await CreateFlow(rootDialog) @@ -174,7 +174,7 @@ public async Task QnAMakerAction_MultiTurnDialogBase_WithNoAnswer() var rootDialog = QnAMakerAction_MultiTurnDialogBase(); var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json"))); - var promptsActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true); + var promptsActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true, CancellationToken.None); var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); await CreateFlow(rootDialog) From b04b0499f7cf975efa41231a44233fe275aba938 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Tue, 2 Jun 2020 23:16:24 +0530 Subject: [PATCH 29/60] For fixing assembly difference issue --- Microsoft.Bot.Builder.sln | 10 ++++++++++ .../Utils/QnACardBuilder.cs | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/Microsoft.Bot.Builder.sln b/Microsoft.Bot.Builder.sln index 27550ff8f2..26c5e314a1 100644 --- a/Microsoft.Bot.Builder.sln +++ b/Microsoft.Bot.Builder.sln @@ -176,6 +176,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Parent", "tests\Skills\Pare EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Child", "tests\Skills\Child\Child.csproj", "{1958FBA4-BF2D-48D9-A5DB-8915F553EBD3}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QnABotAllFeatures", "..\..\BotBuilder-Samples\BotBuilder-Samples\samples\csharp_dotnetcore\49.qnamaker-all-features\QnABotAllFeatures.csproj", "{B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -736,6 +738,14 @@ Global {1958FBA4-BF2D-48D9-A5DB-8915F553EBD3}.Release|Any CPU.Build.0 = Release|Any CPU {1958FBA4-BF2D-48D9-A5DB-8915F553EBD3}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU {1958FBA4-BF2D-48D9-A5DB-8915F553EBD3}.Release-Windows|Any CPU.Build.0 = Release|Any CPU + {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Debug-Windows|Any CPU.ActiveCfg = Debug|Any CPU + {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Debug-Windows|Any CPU.Build.0 = Debug|Any CPU + {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Release|Any CPU.Build.0 = Release|Any CPU + {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU + {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Release-Windows|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index 9aaf57269e..300a9b2d41 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -77,6 +77,17 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, return chatActivity; } + /// + /// Get Card for MultiTurn scenario. (Can be deprecated from 4.10.0 release of sdk). + /// + /// Result to be displayed as prompts. + /// No match text. + /// IMessageActivity. + public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText) + { + return GetQnADefaultResponse(result, true, CancellationToken.None); + } + /// /// Get Card for MultiTurn scenario. (Can be deprecated from 4.10.0 release of sdk). /// From 1e5640c796bfbb463b3df4524fa9bc14cdf0daf4 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Tue, 2 Jun 2020 23:37:10 +0530 Subject: [PATCH 30/60] Revert "For fixing assembly difference issue" This reverts commit b04b0499f7cf975efa41231a44233fe275aba938. --- Microsoft.Bot.Builder.sln | 10 ---------- .../Utils/QnACardBuilder.cs | 11 ----------- 2 files changed, 21 deletions(-) diff --git a/Microsoft.Bot.Builder.sln b/Microsoft.Bot.Builder.sln index 26c5e314a1..27550ff8f2 100644 --- a/Microsoft.Bot.Builder.sln +++ b/Microsoft.Bot.Builder.sln @@ -176,8 +176,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Parent", "tests\Skills\Pare EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Child", "tests\Skills\Child\Child.csproj", "{1958FBA4-BF2D-48D9-A5DB-8915F553EBD3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QnABotAllFeatures", "..\..\BotBuilder-Samples\BotBuilder-Samples\samples\csharp_dotnetcore\49.qnamaker-all-features\QnABotAllFeatures.csproj", "{B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -738,14 +736,6 @@ Global {1958FBA4-BF2D-48D9-A5DB-8915F553EBD3}.Release|Any CPU.Build.0 = Release|Any CPU {1958FBA4-BF2D-48D9-A5DB-8915F553EBD3}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU {1958FBA4-BF2D-48D9-A5DB-8915F553EBD3}.Release-Windows|Any CPU.Build.0 = Release|Any CPU - {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Debug-Windows|Any CPU.ActiveCfg = Debug|Any CPU - {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Debug-Windows|Any CPU.Build.0 = Debug|Any CPU - {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Release|Any CPU.Build.0 = Release|Any CPU - {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU - {B03AF5FE-5E8F-4F1C-A24F-FAAFC4BCF7A8}.Release-Windows|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index 300a9b2d41..9aaf57269e 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -77,17 +77,6 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, return chatActivity; } - /// - /// Get Card for MultiTurn scenario. (Can be deprecated from 4.10.0 release of sdk). - /// - /// Result to be displayed as prompts. - /// No match text. - /// IMessageActivity. - public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText) - { - return GetQnADefaultResponse(result, true, CancellationToken.None); - } - /// /// Get Card for MultiTurn scenario. (Can be deprecated from 4.10.0 release of sdk). /// From ffd0bd8930234668f975e81b7dc7ac98ffc69b98 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Tue, 2 Jun 2020 23:40:47 +0530 Subject: [PATCH 31/60] For assemblies issue --- .../Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index 9aaf57269e..52ef4f46c7 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -82,11 +82,10 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, /// /// Result to be displayed as prompts. /// No match text. - /// cancellationToken. /// IMessageActivity. - public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText, CancellationToken cancellationToken) + public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText) { - return GetQnADefaultResponse(result, true, cancellationToken); + return GetQnADefaultResponse(result, true, CancellationToken.None); } /// From a17d450c5054864e54dfba933884a42e246c4557 Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Wed, 3 Jun 2020 05:23:46 +0530 Subject: [PATCH 32/60] Added purpose of property in summary. --- libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index dbdcb83528..1a50b6a197 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -8,7 +8,8 @@ namespace Microsoft.Bot.Builder.AI.QnA public class AnswerSpanRequest { /// - /// Gets or sets a value indicating whether to enable PreciseAnswer generation or not. + /// Gets or sets a value indicating whether to enable PreciseAnswer generation or not. User can choose to use this feature of QnAMaker + /// Service using this configuration. /// /// /// Choice whether to generate precise answer or not. From 9ce95ce762fad59393e9c3ec6fbd0f445df957ec Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Wed, 3 Jun 2020 05:36:10 +0530 Subject: [PATCH 33/60] Comments improved --- .../Models/AnswerSpanResponse.cs | 5 ++++- .../Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs | 5 +++-- libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs index 6900045b3f..838c65dec0 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs @@ -4,7 +4,10 @@ using Newtonsoft.Json; namespace Microsoft.Bot.Builder.AI.QnA -{ +{ + /// + /// Represents Precise Answer details, these are generated when Precise Answer generation choice is enabled. + /// public class AnswerSpanResponse { /// diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs index d5727e71e0..f1a3eede93 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnADialogResponseOptions.cs @@ -43,10 +43,11 @@ public class QnADialogResponseOptions public Activity CardNoMatchResponse { get; set; } /// - /// Gets or sets a value indicating whether DisplayPreciseAnswerOnly. + /// Gets or sets a value indicating whether the Precise Answer is to be displayed or the source text also + /// chosen to be displayed to the user. /// /// - /// Get or set whether to display Precise Answer Only or Both. + /// Get or set whether to display Precise Answer Only or source text along with Precise Answer. /// public bool DisplayPreciseAnswerOnly { get; set; } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs index 0bcd05d043..6003522ad7 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs @@ -94,7 +94,7 @@ public QnAMakerOptions() public string RankerType { get; set; } /// - /// Gets or sets a value indicating whether enable Precise Answer. + /// Gets or sets a value indicating whether Precise Answer needs to be provided from source text or not. /// /// /// To enable Precise Answer or not. From b56b2465145d83a39f42ec6dbda980bad8ad902a Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Wed, 3 Jun 2020 12:24:46 +0530 Subject: [PATCH 34/60] For Review comments --- .../Models/AnswerSpanResponse.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs index 838c65dec0..fe7de3ac7d 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs @@ -11,7 +11,7 @@ namespace Microsoft.Bot.Builder.AI.QnA public class AnswerSpanResponse { /// - /// Gets or sets the answer text. + /// Gets or sets the Precise Answer text. /// /// /// The answer text. @@ -20,7 +20,7 @@ public class AnswerSpanResponse public string Text { get; set; } /// - /// Gets or sets the answer score. + /// Gets or sets the score of Precise Answer. /// /// /// The answer score. @@ -29,7 +29,7 @@ public class AnswerSpanResponse public float Score { get; set; } /// - /// Gets or sets the answer startIndex. + /// Gets or sets the startIndex of Precise Answer in Source Answer Text. /// /// /// The answer startIndex. @@ -38,7 +38,7 @@ public class AnswerSpanResponse public int StartIndex { get; set; } /// - /// Gets or sets the answer endIndex. + /// Gets or sets the endIndex of PreciseAnswer in Source Answer Text. /// /// /// The answer endIndex. From e651a14e84d0227ca8be3b858025f6ad4670164c Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Wed, 3 Jun 2020 14:46:27 +0530 Subject: [PATCH 35/60] For review comments --- .../Dialogs/QnAMakerDialog.cs | 4 ++-- .../Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 4f78311448..4ae446a667 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -632,7 +632,7 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC var answer = response.First(); - if (!(answer.Context == null || answer.Context.Prompts.Count() == 0)) + if (answer.Context != null && answer.Context.Prompts.Count() > 0) { var previousContextData = ObjectPath.GetPathValue(stepContext.ActiveDialog.State, QnAContextData, new Dictionary()); @@ -662,7 +662,7 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC /// The for the current turn of conversation. /// The for the current turn of conversation. /// A representing the asynchronous operation. - /// If the task is successful, the result contains the response options to use. + /// If the task is successful, the result contains the response options to be used. private async Task DisplayQnAResultAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var dialogOptions = ObjectPath.GetPathValue(stepContext.ActiveDialog.State, Options); diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index 52ef4f46c7..f337f1cf19 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading; -using System.Threading.Tasks; using Microsoft.Bot.Schema; namespace Microsoft.Bot.Builder.AI.QnA @@ -89,12 +88,12 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card } /// - /// Get Card for Default QnA Maker scenario. + /// Get Message Activity Response when User Query is processed by QnAMaker Service. /// - /// Result to be displayed as prompts. - /// renderingchoice. + /// Result consisits of References to other answers, also called as Prompts. + /// Configuration, used for message activity display for multiple options like with or without Precise Answer. /// cancellationToken. - /// IMessageActivity. + /// Message Activity that shall be displayed . public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool displayPreciseAnswerOnly, CancellationToken cancellationToken) { if (result == null) From 7b352266ccbcb277f7a39a826e3562446831bab3 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Sat, 6 Jun 2020 08:34:30 +0530 Subject: [PATCH 36/60] Spellings Syntax --- .../Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs | 2 +- libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 4ae446a667..117d03996f 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -291,7 +291,7 @@ public QnAMakerDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNu public StringExpression RankerType { get; set; } = new StringExpression(RankerTypes.DefaultRankerType); /// - /// Gets or sets a value indicating whether to enable PreciseAnswer Generation. + /// Gets or sets a value indicating whether to enable PreciseAnswer generation. /// /// /// A value indicating whether to enable Precise Answer Feature of QnAMaker Dynamic Answer Generation or not. diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index f337f1cf19..d18e3a5941 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -90,7 +90,7 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card /// /// Get Message Activity Response when User Query is processed by QnAMaker Service. /// - /// Result consisits of References to other answers, also called as Prompts. + /// Result consists of References to other answers, also called as Prompts. /// Configuration, used for message activity display for multiple options like with or without Precise Answer. /// cancellationToken. /// Message Activity that shall be displayed . From 882722373228897e6e684e82a255ab7344ec5190 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Mon, 8 Jun 2020 14:39:54 +0530 Subject: [PATCH 37/60] Content corrections --- .../Dialogs/QnAMakerDialog.cs | 8 ++++---- .../Models/AnswerSpanResponse.cs | 16 ++++++++-------- .../Utils/QnACardBuilder.cs | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 117d03996f..b91980d313 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -294,16 +294,16 @@ public QnAMakerDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNu /// Gets or sets a value indicating whether to enable PreciseAnswer generation. /// /// - /// A value indicating whether to enable Precise Answer Feature of QnAMaker Dynamic Answer Generation or not. + /// A value indicating user's choice between precise answer and full text in response to QnAMaker GenerateAnswer query. /// [JsonProperty("enablePreciseAnswer")] public bool EnablePreciseAnswer { get; set; } /// - /// Gets or sets a value indicating whether gets or sets displayPreciseAnswerOnly. + /// Gets or sets a value indicating whether the user only wants to receive precise answer. /// /// - /// A value indicating whether to display Precise Answer Only or Both Precise Answer and Source Content from which answer is obtained. + /// A value that indicates if user wants to receive full text along with the precise answer or not. /// [JsonProperty("displayPreciseAnswerOnly")] public bool DisplayPreciseAnswerOnly { get; set; } @@ -662,7 +662,7 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC /// The for the current turn of conversation. /// The for the current turn of conversation. /// A representing the asynchronous operation. - /// If the task is successful, the result contains the response options to be used. + /// If the task is successful, the result contains the as per user's choice. private async Task DisplayQnAResultAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var dialogOptions = ObjectPath.GetPathValue(stepContext.ActiveDialog.State, Options); diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs index fe7de3ac7d..34960f43d5 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/AnswerSpanResponse.cs @@ -6,7 +6,7 @@ namespace Microsoft.Bot.Builder.AI.QnA { /// - /// Represents Precise Answer details, these are generated when Precise Answer generation choice is enabled. + /// This class helps in identifying the precise answer within complete answer text. /// public class AnswerSpanResponse { @@ -14,34 +14,34 @@ public class AnswerSpanResponse /// Gets or sets the Precise Answer text. /// /// - /// The answer text. + /// The precise answer text relevant to the user query. /// [JsonProperty("text")] public string Text { get; set; } /// - /// Gets or sets the score of Precise Answer. + /// Gets or sets the score of the Precise Answer. /// /// - /// The answer score. + /// The answer score pertaining to the quality of precise answer text. /// [JsonProperty("score")] public float Score { get; set; } /// - /// Gets or sets the startIndex of Precise Answer in Source Answer Text. + /// Gets or sets the startIndex of the Precise Answer within the full answer text. /// /// - /// The answer startIndex. + /// The starting index for the precise answer generated. /// [JsonProperty("startIndex")] public int StartIndex { get; set; } /// - /// Gets or sets the endIndex of PreciseAnswer in Source Answer Text. + /// Gets or sets the endIndex of PreciseAnswer within the full answer text. /// /// - /// The answer endIndex. + /// The end index for the precise answer generated. /// [JsonProperty("endIndex")] public int EndIndex { get; set; } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index d18e3a5941..62ad0babe2 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -79,7 +79,7 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, /// /// Get Card for MultiTurn scenario. (Can be deprecated from 4.10.0 release of sdk). /// - /// Result to be displayed as prompts. + /// Result to be displayed. /// No match text. /// IMessageActivity. public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText) @@ -88,12 +88,12 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card } /// - /// Get Message Activity Response when User Query is processed by QnAMaker Service. + /// Get Answer Card. /// /// Result consists of References to other answers, also called as Prompts. - /// Configuration, used for message activity display for multiple options like with or without Precise Answer. + /// Parameter representing if user wants full text along with precise answer or not. /// cancellationToken. - /// Message Activity that shall be displayed . + /// IMessageActivity. public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool displayPreciseAnswerOnly, CancellationToken cancellationToken) { if (result == null) From 07ee9e5f04af2a88f3bc2c5057068deffdf66a24 Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Mon, 8 Jun 2020 15:40:52 +0530 Subject: [PATCH 38/60] Content comments changes --- .../Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index 62ad0babe2..d9e32cdea6 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -91,8 +91,8 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card /// Get Answer Card. /// /// Result consists of References to other answers, also called as Prompts. - /// Parameter representing if user wants full text along with precise answer or not. - /// cancellationToken. + /// Parameter to set either of the two choices: 1. Precise answer only 2. Precise answer and corresponding text. + /// Cancellation Token. /// IMessageActivity. public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool displayPreciseAnswerOnly, CancellationToken cancellationToken) { From d9d42bb33de2bf99f92417b7441b270dd2bd9ffa Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Mon, 8 Jun 2020 15:47:59 +0530 Subject: [PATCH 39/60] content request --- libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index 1a50b6a197..fe4ec293b9 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -5,11 +5,13 @@ namespace Microsoft.Bot.Builder.AI.QnA { + /// + /// This class helps user to opt for precise answer. + /// public class AnswerSpanRequest { /// - /// Gets or sets a value indicating whether to enable PreciseAnswer generation or not. User can choose to use this feature of QnAMaker - /// Service using this configuration. + /// Gets or sets a value indicating whether user wants precise answer. /// /// /// Choice whether to generate precise answer or not. From be73b1e65614f24cc1719f296156a031725ff3d3 Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Mon, 8 Jun 2020 20:38:54 +0530 Subject: [PATCH 40/60] content changes --- libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index fe4ec293b9..c597f7279f 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -11,11 +11,13 @@ namespace Microsoft.Bot.Builder.AI.QnA public class AnswerSpanRequest { /// - /// Gets or sets a value indicating whether user wants precise answer. + /// Gets or sets a value indicating whether to enable PreciseAnswer generation or not. User can choose to use this feature of QnAMaker + /// Service using this configuration. /// /// /// Choice whether to generate precise answer or not. /// + /// [JsonProperty("enable")] public bool Enable { get; set; } } From 3f57d1fbde7bd95f88c473411ef2e7afbbdd74ff Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Mon, 8 Jun 2020 20:53:53 +0530 Subject: [PATCH 41/60] Content changes for comments --- .../Dialogs/QnAMakerDialog.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 4ae446a667..a4cf8f9e9f 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -291,19 +291,19 @@ public QnAMakerDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNu public StringExpression RankerType { get; set; } = new StringExpression(RankerTypes.DefaultRankerType); /// - /// Gets or sets a value indicating whether to enable PreciseAnswer Generation. + /// Gets or sets a value indicating whether to enable PreciseAnswer generation. /// /// - /// A value indicating whether to enable Precise Answer Feature of QnAMaker Dynamic Answer Generation or not. + /// A value indicating user's choice between precise answer and full text in response to QnAMaker GenerateAnswer query. /// [JsonProperty("enablePreciseAnswer")] public bool EnablePreciseAnswer { get; set; } /// - /// Gets or sets a value indicating whether gets or sets displayPreciseAnswerOnly. + /// Gets or sets a value indicating whether the user only wants to receive precise answer. /// /// - /// A value indicating whether to display Precise Answer Only or Both Precise Answer and Source Content from which answer is obtained. + /// A value that indicates if user wants to receive full text along with the precise answer or not. /// [JsonProperty("displayPreciseAnswerOnly")] public bool DisplayPreciseAnswerOnly { get; set; } @@ -662,7 +662,8 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC /// The for the current turn of conversation. /// The for the current turn of conversation. /// A representing the asynchronous operation. - /// If the task is successful, the result contains the response options to be used. + /// If the task is successful, the result contains the as per user's choice. + private async Task DisplayQnAResultAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var dialogOptions = ObjectPath.GetPathValue(stepContext.ActiveDialog.State, Options); From 1a06a9280da9ccf71709c6fad4cb70546ed431cb Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Mon, 8 Jun 2020 21:18:53 +0530 Subject: [PATCH 42/60] Content review updates --- .../Utils/QnACardBuilder.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index f337f1cf19..d9e32cdea6 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -79,7 +79,7 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, /// /// Get Card for MultiTurn scenario. (Can be deprecated from 4.10.0 release of sdk). /// - /// Result to be displayed as prompts. + /// Result to be displayed. /// No match text. /// IMessageActivity. public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText) @@ -88,12 +88,12 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card } /// - /// Get Message Activity Response when User Query is processed by QnAMaker Service. + /// Get Answer Card. /// - /// Result consisits of References to other answers, also called as Prompts. - /// Configuration, used for message activity display for multiple options like with or without Precise Answer. - /// cancellationToken. - /// Message Activity that shall be displayed . + /// Result consists of References to other answers, also called as Prompts. + /// Parameter to set either of the two choices: 1. Precise answer only 2. Precise answer and corresponding text. + /// Cancellation Token. + /// IMessageActivity. public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool displayPreciseAnswerOnly, CancellationToken cancellationToken) { if (result == null) From 2152ae594610f06a4fcbe13401a9102add3c741c Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Mon, 8 Jun 2020 23:45:57 +0530 Subject: [PATCH 43/60] Content changes --- libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index a4cf8f9e9f..b91980d313 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -663,7 +663,6 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC /// The for the current turn of conversation. /// A representing the asynchronous operation. /// If the task is successful, the result contains the as per user's choice. - private async Task DisplayQnAResultAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var dialogOptions = ObjectPath.GetPathValue(stepContext.ActiveDialog.State, Options); From d6cf4c630b72769f182d3f7c1b08a75057dd6b1b Mon Sep 17 00:00:00 2001 From: Vijaya Peketi Date: Mon, 8 Jun 2020 23:49:11 +0530 Subject: [PATCH 44/60] content chagnes --- .../AnswerSpanRequest.cs | 3 +-- .../QnAMakerRecognizer.cs | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index c597f7279f..69add0fb9f 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -16,8 +16,7 @@ public class AnswerSpanRequest /// /// /// Choice whether to generate precise answer or not. - /// - /// + /// [JsonProperty("enable")] public bool Enable { get; set; } } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs index dc7ed47fe8..d656a9676b 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs @@ -140,7 +140,14 @@ public QnAMakerRecognizer() [JsonProperty("logPersonalInformation")] public BoolExpression LogPersonalInformation { get; set; } = "=settings.telemetry.logPersonalInformation"; - public bool EnablePreciseAnswer { get; set; } + /// + /// Gets or sets a value indicating whether Precise Answer needs to be provided from source text or not. + /// + /// + /// To enable Precise Answer or not. + /// + [JsonProperty("enablePreciseAnswer")] + public BoolExpression EnablePreciseAnswer { get; set; } = true; public override async Task RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken, Dictionary telemetryProperties = null, Dictionary telemetryMetrics = null) { @@ -183,7 +190,7 @@ public override async Task RecognizeAsync(DialogContext dialog QnAId = this.QnAId.GetValue(dialogContext.State), RankerType = this.RankerType.GetValue(dialogContext.State), IsTest = this.IsTest, - EnablePreciseAnswer = this.EnablePreciseAnswer + EnablePreciseAnswer = this.EnablePreciseAnswer.GetValue(dialogContext.State) }, null).ConfigureAwait(false); @@ -211,6 +218,15 @@ public override async Task RecognizeAsync(DialogContext dialog answerArray.Add(topAnswer.Answer); ObjectPath.SetPathValue(recognizerResult, "entities.answer", answerArray); + // if answerSpan in topAnswer.answerSpan + var preciseAnswer = topAnswer.AnswerSpan; + if ((preciseAnswer != null) && !string.IsNullOrEmpty(preciseAnswer.Text)) + { + var answerSpanArray = new JArray(); + answerArray.Add(topAnswer.Answer); + ObjectPath.SetPathValue(recognizerResult, "entities.preciseAnswer", answerSpanArray); + } + var instance = new JArray(); instance.Add(JObject.FromObject(topAnswer)); ObjectPath.SetPathValue(recognizerResult, "entities.$instance.answer", instance); From 1eb0c1017fcdeab6f9723bfdb9daf7b342c4e47a Mon Sep 17 00:00:00 2001 From: vipeketi Date: Tue, 9 Jun 2020 16:05:38 +0530 Subject: [PATCH 45/60] Revert enablePreciseAnswer to bool --- .../Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs index d656a9676b..744d48dd3c 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs @@ -147,7 +147,7 @@ public QnAMakerRecognizer() /// To enable Precise Answer or not. /// [JsonProperty("enablePreciseAnswer")] - public BoolExpression EnablePreciseAnswer { get; set; } = true; + public bool EnablePreciseAnswer { get; set; } = true; public override async Task RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken, Dictionary telemetryProperties = null, Dictionary telemetryMetrics = null) { @@ -190,7 +190,7 @@ public override async Task RecognizeAsync(DialogContext dialog QnAId = this.QnAId.GetValue(dialogContext.State), RankerType = this.RankerType.GetValue(dialogContext.State), IsTest = this.IsTest, - EnablePreciseAnswer = this.EnablePreciseAnswer.GetValue(dialogContext.State) + EnablePreciseAnswer = this.EnablePreciseAnswer }, null).ConfigureAwait(false); @@ -201,7 +201,7 @@ public override async Task RecognizeAsync(DialogContext dialog { if ((topAnswer == null) || (answer.Score > topAnswer.Score)) { - topAnswer = answer; + topAnswer = answer; } } From 7b94291a6bf5107a436452f4abf1c1351ed2d181 Mon Sep 17 00:00:00 2001 From: vipeketi Date: Tue, 9 Jun 2020 17:35:16 +0530 Subject: [PATCH 46/60] removing json property for enable preccise --- libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs index 744d48dd3c..bcfe170063 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs @@ -146,7 +146,6 @@ public QnAMakerRecognizer() /// /// To enable Precise Answer or not. /// - [JsonProperty("enablePreciseAnswer")] public bool EnablePreciseAnswer { get; set; } = true; public override async Task RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken, Dictionary telemetryProperties = null, Dictionary telemetryMetrics = null) From 60d5fda0060a6962aa3e49bdbf0a28329acf5eff Mon Sep 17 00:00:00 2001 From: vipeketi Date: Tue, 9 Jun 2020 23:39:04 +0530 Subject: [PATCH 47/60] Reverting Recognizer changes --- .../QnAMakerRecognizer.cs | 20 +------------------ .../QnAMakerRecognizerTests.cs | 8 ++++++-- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs index bcfe170063..5696a494a5 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs @@ -140,14 +140,6 @@ public QnAMakerRecognizer() [JsonProperty("logPersonalInformation")] public BoolExpression LogPersonalInformation { get; set; } = "=settings.telemetry.logPersonalInformation"; - /// - /// Gets or sets a value indicating whether Precise Answer needs to be provided from source text or not. - /// - /// - /// To enable Precise Answer or not. - /// - public bool EnablePreciseAnswer { get; set; } = true; - public override async Task RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken, Dictionary telemetryProperties = null, Dictionary telemetryMetrics = null) { // Identify matched intents @@ -188,8 +180,7 @@ public override async Task RecognizeAsync(DialogContext dialog Top = this.Top.GetValue(dialogContext.State), QnAId = this.QnAId.GetValue(dialogContext.State), RankerType = this.RankerType.GetValue(dialogContext.State), - IsTest = this.IsTest, - EnablePreciseAnswer = this.EnablePreciseAnswer + IsTest = this.IsTest }, null).ConfigureAwait(false); @@ -217,15 +208,6 @@ public override async Task RecognizeAsync(DialogContext dialog answerArray.Add(topAnswer.Answer); ObjectPath.SetPathValue(recognizerResult, "entities.answer", answerArray); - // if answerSpan in topAnswer.answerSpan - var preciseAnswer = topAnswer.AnswerSpan; - if ((preciseAnswer != null) && !string.IsNullOrEmpty(preciseAnswer.Text)) - { - var answerSpanArray = new JArray(); - answerArray.Add(topAnswer.Answer); - ObjectPath.SetPathValue(recognizerResult, "entities.preciseAnswer", answerSpanArray); - } - var instance = new JArray(); instance.Add(JObject.FromObject(topAnswer)); ObjectPath.SetPathValue(recognizerResult, "entities.$instance.answer", instance); diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs index 907369fe07..e5714e17cb 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs @@ -61,6 +61,12 @@ public AdaptiveDialog QnAMakerRecognizer_DialogBase() mockHttp.When(HttpMethod.Post, GetRequestUrl()) .WithContent("{\"question\":\"QnaMaker_ReturnsAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer.json")); + mockHttp.When(HttpMethod.Post, GetRequestUrl()) + .WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); + mockHttp.When(HttpMethod.Post, GetRequestUrl()) + .WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) .WithContent("{\"question\":\"QnaMaker_ReturnsNoAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") .Respond("application/json", GetResponse("QnaMaker_ReturnsNoAnswer.json")); @@ -78,9 +84,7 @@ public AdaptiveDialog QnAMakerRecognizer_DialogBase() public async Task QnAMakerRecognizer_WithTopNAnswer() { var rootDialog = QnAMakerRecognizer_DialogBase(); - var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_TopNAnswer.json"))); - await CreateFlow(rootDialog) .Send("QnaMaker_TopNAnswer") .AssertReply(response.Answers[0].Answer) From 757ee08e0042166e3a7412234fd06838f52152b9 Mon Sep 17 00:00:00 2001 From: vipeketi Date: Wed, 10 Jun 2020 12:40:10 +0530 Subject: [PATCH 48/60] schema change and BoolExpression --- .../Dialogs/QnAMakerDialog.cs | 4 +- .../Schemas/Microsoft.QnAMakerDialog.schema | 219 +++++++++--------- 2 files changed, 114 insertions(+), 109 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index b91980d313..75804a95d8 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -297,7 +297,7 @@ public QnAMakerDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNu /// A value indicating user's choice between precise answer and full text in response to QnAMaker GenerateAnswer query. /// [JsonProperty("enablePreciseAnswer")] - public bool EnablePreciseAnswer { get; set; } + public BoolExpression EnablePreciseAnswer { get; set; } /// /// Gets or sets a value indicating whether the user only wants to receive precise answer. @@ -446,7 +446,7 @@ protected virtual Task GetQnAMakerOptionsAsync(DialogContext dc QnAId = 0, RankerType = this.RankerType?.GetValue(dc.State), IsTest = this.IsTest, - EnablePreciseAnswer = this.EnablePreciseAnswer + EnablePreciseAnswer = this.EnablePreciseAnswer.GetValue(dc.State) }); } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema index 17b2a95a12..9a92437812 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema @@ -5,115 +5,120 @@ "description": "Dialog which uses QnAMAker knowledge base to answer questions.", "type": "object", "additionalProperties": false, - "properties": { - "knowledgeBaseId": { - "$ref": "schema:#/definitions/stringExpression", - "title": "KnowledgeBase Id", - "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", - "default": "=settings.qna.knowledgebaseid" - }, - "endpointKey": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Endpoint Key", - "description": "Endpoint key for the QnA Maker KB.", - "default": "=settings.qna.endpointkey" - }, - "hostname": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Hostname", - "description": "Hostname for your QnA Maker service.", - "default": "=settings.qna.hostname", - "examples": [ - "https://yourserver.azurewebsites.net/qnamaker" - ] - }, - "noAnswer": { - "$kind": "Microsoft.IActivityTemplate", - "title": "Fallback answer", - "description": "Default answer to return when none found in KB.", - "default": "Sorry, I did not find an answer." - }, - "threshold": { - "$ref": "schema:#/definitions/numberExpression", - "title": "Threshold", - "description": "Threshold score to filter results.", - "default": 0.3 - }, - "activeLearningCardTitle": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Active learning card title", - "description": "Title for active learning suggestions card.", - "default": "Did you mean:" - }, - "cardNoMatchText": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Card no match text", - "description": "Text for no match option.", - "default": "None of the above." - }, - "cardNoMatchResponse": { - "$kind": "Microsoft.IActivityTemplate", - "title": "Card no match response", - "description": "Custom response when no match option was selected.", - "default": "Thanks for the feedback." - }, - "strictFilters": { - "$ref": "schema:#/definitions/arrayExpression", - "title": "Strict Filters", - "description": "Metadata filters to use when calling the QnA Maker KB.", - "items": { - "type": "object", - "title": "Metadata filter", - "description": "Metadata filter.", - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "Name of filter property.", - "maximum": 100 - }, - "value": { - "type": "string", - "title": "Value", - "description": "Value to filter on.", - "maximum": 100 - } - } - } - }, - "top": { - "$ref": "schema:#/definitions/numberExpression", - "title": "Top", - "description": "The number of answers you want to retrieve.", - "default": 3 - }, - "isTest": { - "type": "boolean", - "title": "IsTest", - "description": "True, if pointing to Test environment, else false.", - "default": false - }, - "rankerType": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Ranker Type", - "description": "Type of Ranker.", - "oneOf": [ - { - "title": "Standard ranker", - "description": "Standard ranker types.", - "enum": [ - "default", - "questionOnly", - "autoSuggestQuestion" - ], - "default": "default" - }, - { - "$ref": "schema:#/definitions/equalsExpression" - } - ] + "properties": { + "knowledgeBaseId": { + "$ref": "schema:#/definitions/stringExpression", + "title": "KnowledgeBase Id", + "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", + "default": "=settings.qna.knowledgebaseid" + }, + "endpointKey": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Endpoint Key", + "description": "Endpoint key for the QnA Maker KB.", + "default": "=settings.qna.endpointkey" + }, + "hostname": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Hostname", + "description": "Hostname for your QnA Maker service.", + "default": "=settings.qna.hostname", + "examples": [ + "https://yourserver.azurewebsites.net/qnamaker" + ] + }, + "noAnswer": { + "$kind": "Microsoft.IActivityTemplate", + "title": "Fallback answer", + "description": "Default answer to return when none found in KB.", + "default": "Sorry, I did not find an answer." + }, + "threshold": { + "$ref": "schema:#/definitions/numberExpression", + "title": "Threshold", + "description": "Threshold score to filter results.", + "default": 0.3 + }, + "activeLearningCardTitle": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Active learning card title", + "description": "Title for active learning suggestions card.", + "default": "Did you mean:" + }, + "cardNoMatchText": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Card no match text", + "description": "Text for no match option.", + "default": "None of the above." + }, + "cardNoMatchResponse": { + "$kind": "Microsoft.IActivityTemplate", + "title": "Card no match response", + "description": "Custom response when no match option was selected.", + "default": "Thanks for the feedback." + }, + "strictFilters": { + "$ref": "schema:#/definitions/arrayExpression", + "title": "Strict Filters", + "description": "Metadata filters to use when calling the QnA Maker KB.", + "items": { + "type": "object", + "title": "Metadata filter", + "description": "Metadata filter.", + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "Name of filter property.", + "maximum": 100 + }, + "value": { + "type": "string", + "title": "Value", + "description": "Value to filter on.", + "maximum": 100 + } } + } + }, + "top": { + "$ref": "schema:#/definitions/numberExpression", + "title": "Top", + "description": "The number of answers you want to retrieve.", + "default": 3 + }, + "isTest": { + "type": "boolean", + "title": "IsTest", + "description": "True, if pointing to Test environment, else false.", + "default": false }, + "enablePreciseAnswer": { + "$ref": "schema:#/definitions/booleanExpression", + "title": "EnablePreciseAnswer", + "description": "True, if precise answer is opted, else false." + }, + "rankerType": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Ranker Type", + "description": "Type of Ranker.", + "oneOf": [ + { + "title": "Standard ranker", + "description": "Standard ranker types.", + "enum": [ + "default", + "questionOnly", + "autoSuggestQuestion" + ], + "default": "default" + }, + { + "$ref": "schema:#/definitions/equalsExpression" + } + ] + } + }, "required": [ "knowledgeBaseId", "endpointKey", From cb8cfcfcb35240890c4e6ef8ed303a76c5977163 Mon Sep 17 00:00:00 2001 From: vipeketi Date: Wed, 10 Jun 2020 13:02:38 +0530 Subject: [PATCH 49/60] Review comments --- .../QnAMakerCardEqualityComparer.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs index 8c1c66d4b4..3d0f5e1515 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs @@ -45,7 +45,12 @@ public bool Equals(IActivity x, IActivity y) } } - return string.Equals(activity1.Text, activity2.Text); + if (!string.Equals(activity1.Text, activity2.Text)) + { + return false; + } + + return true; } public int GetHashCode(IActivity obj) From 11c9fa13049f6057a9b18a88367f9dee7546c178 Mon Sep 17 00:00:00 2001 From: vipeketi Date: Wed, 10 Jun 2020 14:01:46 +0530 Subject: [PATCH 50/60] initialization of EnablePreciseAnswer --- .../Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 75804a95d8..cee28b31a7 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -297,7 +297,7 @@ public QnAMakerDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNu /// A value indicating user's choice between precise answer and full text in response to QnAMaker GenerateAnswer query. /// [JsonProperty("enablePreciseAnswer")] - public BoolExpression EnablePreciseAnswer { get; set; } + public BoolExpression EnablePreciseAnswer { get; set; } = false; /// /// Gets or sets a value indicating whether the user only wants to receive precise answer. From 7b0c684fd7003a24b39d1a0a84111c6572f1447f Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Wed, 10 Jun 2020 22:19:51 +0530 Subject: [PATCH 51/60] schema changes for Display Precise AnswerOnly --- .../Schemas/Microsoft.QnAMakerDialog.schema | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema index 9a92437812..832a652122 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema @@ -93,6 +93,12 @@ "description": "True, if pointing to Test environment, else false.", "default": false }, + "displayPreciseAnswerOnly": { + "type": "boolean", + "title": "DisplayPreciseAnswerOnly", + "description": "True, if only precise answer needs to be displayed, else false.", + "default": false + }, "enablePreciseAnswer": { "$ref": "schema:#/definitions/booleanExpression", "title": "EnablePreciseAnswer", From d144de8717f761f691e2d25c84f41fd2e47b59bb Mon Sep 17 00:00:00 2001 From: vipeketi Date: Thu, 11 Jun 2020 08:50:36 +0530 Subject: [PATCH 52/60] BoolExpression for DisplayPreciseAnswerOnly --- .../Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs | 4 ++-- .../Schemas/Microsoft.QnAMakerDialog.schema | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index cee28b31a7..19b4385a9d 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -306,7 +306,7 @@ public QnAMakerDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNu /// A value that indicates if user wants to receive full text along with the precise answer or not. /// [JsonProperty("displayPreciseAnswerOnly")] - public bool DisplayPreciseAnswerOnly { get; set; } + public BoolExpression DisplayPreciseAnswerOnly { get; set; } = true; /// /// Called when the dialog is started and pushed onto the dialog stack. @@ -464,7 +464,7 @@ protected virtual async Task GetQnAResponseOptionsAsyn ActiveLearningCardTitle = this.ActiveLearningCardTitle?.GetValue(dc.State) ?? DefaultCardTitle, CardNoMatchText = this.CardNoMatchText?.GetValue(dc.State) ?? DefaultCardNoMatchText, CardNoMatchResponse = await this.CardNoMatchResponse.BindAsync(dc).ConfigureAwait(false), - DisplayPreciseAnswerOnly = this.DisplayPreciseAnswerOnly + DisplayPreciseAnswerOnly = this.DisplayPreciseAnswerOnly.GetValue(dc.State) }; } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema index 9a92437812..64bdd2ed35 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema @@ -98,6 +98,11 @@ "title": "EnablePreciseAnswer", "description": "True, if precise answer is opted, else false." }, + "displayPreciseAnswerOnly": { + "$ref": "schema:#/definitions/booleanExpression", + "title": "DisplayPreciseAnswerOnly", + "description": "True, if precise answer is opted, else false." + }, "rankerType": { "$ref": "schema:#/definitions/stringExpression", "title": "Ranker Type", From 331bfc7aabe924d1d6a3273fa3d632e8bf8b77cd Mon Sep 17 00:00:00 2001 From: vipeketi <58211229+vipeketi@users.noreply.github.com> Date: Tue, 16 Jun 2020 09:24:36 +0530 Subject: [PATCH 53/60] bool property for displayPreciseAnswer --- .../Schemas/Microsoft.QnAMakerDialog.schema | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema index 5879590265..0ba17d8faa 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema @@ -92,12 +92,6 @@ "title": "IsTest", "description": "True, if pointing to Test environment, else false.", "default": false - }, - "displayPreciseAnswerOnly": { - "type": "boolean", - "title": "DisplayPreciseAnswerOnly", - "description": "True, if only precise answer needs to be displayed, else false.", - "default": false }, "enablePreciseAnswer": { "$ref": "schema:#/definitions/booleanExpression", @@ -107,7 +101,7 @@ "displayPreciseAnswerOnly": { "$ref": "schema:#/definitions/booleanExpression", "title": "DisplayPreciseAnswerOnly", - "description": "True, if precise answer is opted, else false." + "description": "True, if precise answer text only is opted, else false." }, "rankerType": { "$ref": "schema:#/definitions/stringExpression", From 27fe97bf40f9be58e437482d629f3a4417f37659 Mon Sep 17 00:00:00 2001 From: vipeketi Date: Tue, 16 Jun 2020 14:51:22 +0530 Subject: [PATCH 54/60] Updated comments --- .../Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs | 6 +++--- .../QnAMakerCardEqualityComparer.cs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index d9e32cdea6..5aadad93a3 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -93,7 +93,7 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card /// Result consists of References to other answers, also called as Prompts. /// Parameter to set either of the two choices: 1. Precise answer only 2. Precise answer and corresponding text. /// Cancellation Token. - /// IMessageActivity. + /// Message activity for Query Result. public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool displayPreciseAnswerOnly, CancellationToken cancellationToken) { if (result == null) @@ -123,7 +123,7 @@ public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool di } } - string heroCardText = null; + string heroCardText = string.Empty; if (!string.IsNullOrWhiteSpace(result?.AnswerSpan?.Text)) { chatActivity.Text = result.AnswerSpan.Text; @@ -137,7 +137,7 @@ public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool di if (buttonList != null || !string.IsNullOrWhiteSpace(heroCardText)) { - var plCard = new HeroCard(); + var plCard = new HeroCard(); if (buttonList != null) { diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs index 3d0f5e1515..d442dcc786 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs @@ -30,13 +30,14 @@ public bool Equals(IActivity x, IActivity y) return false; } + //Return false if only one of the attachments is null. if ((activity1.Attachments == null && activity2.Attachments != null) || (activity1.Attachments != null && activity2.Attachments == null)) { return false; } - // Check for attachments + // Check for attachments only if neither of the attachments are null. if (activity1.Attachments != null && activity2.Attachments != null) { if (activity1.Attachments.Count != activity2.Attachments.Count) From 41708f89c2182b368d287e46285489b03f16a6f2 Mon Sep 17 00:00:00 2001 From: vipeketi Date: Wed, 17 Jun 2020 00:13:06 +0530 Subject: [PATCH 55/60] Null checks and CardEqualityComparer comments --- .../Dialogs/QnAMakerDialog.cs | 10 +++---- .../Utils/GenerateAnswerUtils.cs | 13 ++++---- .../Utils/QnACardBuilder.cs | 17 +++++------ .../Microsoft.Bot.Schema/ContentTypes.cs | 6 ++++ .../QnAMakerCardEqualityComparer.cs | 30 ++++++------------- .../QnAMakerRecognizerTests.cs | 12 ++++---- .../QnAMakerTests.cs | 12 ++++---- 7 files changed, 45 insertions(+), 55 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 19b4385a9d..573163b79c 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -513,7 +513,7 @@ private async Task CallGenerateAnswerAsync(WaterfallStepContex // Get active learning suggestion card activity. var message = QnACardBuilder.GetSuggestionsCard(suggestedQuestions, dialogOptions.ResponseOptions.ActiveLearningCardTitle, dialogOptions.ResponseOptions.CardNoMatchText); - await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false); + await stepContext.Context.SendActivityAsync(message, cancellationToken).ConfigureAwait(false); ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions); stepContext.State.SetValue($"this.suggestedQuestions", suggestedQuestions); @@ -646,8 +646,8 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions); // Get multi-turn prompts card activity. - var message = QnACardBuilder.GetQnADefaultResponse(answer, dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly, cancellationToken); - await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false); + var message = QnACardBuilder.GetQnADefaultResponse(answer, dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly); + await stepContext.Context.SendActivityAsync(message, cancellationToken).ConfigureAwait(false); return new DialogTurnResult(DialogTurnStatus.Waiting); } @@ -694,8 +694,8 @@ private async Task DisplayQnAResultAsync(WaterfallStepContext // If response is present then show that response, else default answer. if (stepContext.Result is List response && response.Count > 0) { - var message = QnACardBuilder.GetQnADefaultResponse(response.First(), dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly, cancellationToken); - await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false); + var message = QnACardBuilder.GetQnADefaultResponse(response.First(), dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly); + await stepContext.Context.SendActivityAsync(message, cancellationToken).ConfigureAwait(false); } else { diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs index 7829ff2e8d..2996d8dfd5 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs @@ -156,12 +156,12 @@ private QnAMakerOptions HydrateOptions(QnAMakerOptions queryOptions) if (queryOptions != null) { - if (queryOptions.ScoreThreshold != hydratedOptions.ScoreThreshold && queryOptions.ScoreThreshold != 0) + if (queryOptions.ScoreThreshold != 0) { hydratedOptions.ScoreThreshold = queryOptions.ScoreThreshold; } - if (queryOptions.Top != hydratedOptions.Top && queryOptions.Top != 0) + if (queryOptions.Top != 0) { hydratedOptions.Top = queryOptions.Top; } @@ -184,10 +184,10 @@ private QnAMakerOptions HydrateOptions(QnAMakerOptions queryOptions) private async Task QueryQnaServiceAsync(Activity messageActivity, QnAMakerOptions options) { var requestUrl = $"{_endpoint.Host}/knowledgebases/{_endpoint.KnowledgeBaseId}/generateanswer"; - AnswerSpanRequest answerSpanRequest = null; + var answerSpanRequest = new AnswerSpanRequest(); if (options.EnablePreciseAnswer) { - answerSpanRequest = new AnswerSpanRequest { Enable = options.EnablePreciseAnswer }; + answerSpanRequest.Enable = options.EnablePreciseAnswer; } var jsonRequest = JsonConvert.SerializeObject( @@ -214,10 +214,9 @@ private async Task QueryQnaServiceAsync(Activity messageActivity, private async Task EmitTraceInfoAsync(ITurnContext turnContext, Activity messageActivity, QueryResult[] result, QnAMakerOptions options) { - AnswerSpanRequest answerSpanRequest = null; + var answerSpanRequest = new AnswerSpanRequest(); if (options.EnablePreciseAnswer) - { - answerSpanRequest = new AnswerSpanRequest(); + { answerSpanRequest.Enable = options.EnablePreciseAnswer; } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index 5aadad93a3..74673df54d 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -84,17 +84,16 @@ public static IMessageActivity GetSuggestionsCard(List suggestionsList, /// IMessageActivity. public static IMessageActivity GetQnAPromptsCard(QueryResult result, string cardNoMatchText) { - return GetQnADefaultResponse(result, true, CancellationToken.None); + return GetQnADefaultResponse(result, true); } /// /// Get Answer Card. /// - /// Result consists of References to other answers, also called as Prompts. - /// Parameter to set either of the two choices: 1. Precise answer only 2. Precise answer and corresponding text. - /// Cancellation Token. + /// Result consists of Answer, Precise Answer (Optionally) and References to other answers, also called as Prompts. + /// Parameter to set either of the two choices: 1. Precise answer only 2. Precise answer and corresponding text. /// Message activity for Query Result. - public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool displayPreciseAnswerOnly, CancellationToken cancellationToken) + public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool displayPreciseAnswerOnly) { if (result == null) { @@ -104,12 +103,10 @@ public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool di var chatActivity = Activity.CreateMessageActivity(); chatActivity.Text = result.Answer; - List buttonList = null; + var buttonList = new List(); if (result?.Context?.Prompts != null && result.Context.Prompts.Any()) { - buttonList = new List(); - // Add all prompt foreach (var prompt in result.Context.Prompts) { @@ -135,11 +132,11 @@ public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool di } } - if (buttonList != null || !string.IsNullOrWhiteSpace(heroCardText)) + if (buttonList.Any() || !string.IsNullOrWhiteSpace(heroCardText)) { var plCard = new HeroCard(); - if (buttonList != null) + if (buttonList.Any()) { plCard.Buttons = buttonList; } diff --git a/libraries/Microsoft.Bot.Schema/ContentTypes.cs b/libraries/Microsoft.Bot.Schema/ContentTypes.cs index aefbae5f01..cb0f1e818f 100644 --- a/libraries/Microsoft.Bot.Schema/ContentTypes.cs +++ b/libraries/Microsoft.Bot.Schema/ContentTypes.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.Diagnostics.CodeAnalysis; namespace Microsoft.Bot.Schema @@ -21,6 +22,11 @@ public partial class ThumbnailCard public partial class HeroCard { public const string ContentType = "application/vnd.microsoft.card.hero"; + + public static explicit operator HeroCard(Attachment v) + { + throw new NotImplementedException(); + } } /// diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs index d442dcc786..8d942eecb7 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerCardEqualityComparer.cs @@ -24,34 +24,22 @@ public bool Equals(IActivity x, IActivity y) var activity1 = x.AsMessageActivity(); var activity2 = y.AsMessageActivity(); + + int activity1AttachmentCount = 0; + int activity2AttachmentCount = 0; - if (activity1 == null || activity2 == null) + if (activity1?.Attachments != null) { - return false; - } - - //Return false if only one of the attachments is null. - if ((activity1.Attachments == null && activity2.Attachments != null) || - (activity1.Attachments != null && activity2.Attachments == null)) - { - return false; + activity1AttachmentCount = activity1.Attachments.Count; } - // Check for attachments only if neither of the attachments are null. - if (activity1.Attachments != null && activity2.Attachments != null) + if (activity2?.Attachments != null) { - if (activity1.Attachments.Count != activity2.Attachments.Count) - { - return false; - } - } - - if (!string.Equals(activity1.Text, activity2.Text)) - { - return false; + activity2AttachmentCount = activity2.Attachments.Count; } - return true; + return (activity1AttachmentCount == activity2AttachmentCount) && + string.Equals(activity1?.Text, activity2?.Text); } public int GetHashCode(IActivity obj) diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs index e5714e17cb..41e4d647ff 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs @@ -59,22 +59,22 @@ public AdaptiveDialog QnAMakerRecognizer_DialogBase() { var mockHttp = new MockHttpMessageHandler(); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_ReturnsAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + .WithContent("{\"question\":\"QnaMaker_ReturnsAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + .WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + .WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_ReturnsNoAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + .WithContent("{\"question\":\"QnaMaker_ReturnsNoAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsNoAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_TopNAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + .WithContent("{\"question\":\"QnaMaker_TopNAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"QnaMaker_ReturnsAnswerWithIntent\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + .WithContent("{\"question\":\"QnaMaker_ReturnsAnswerWithIntent\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswerWithIntent.json")); return CreateQnAMakerActionDialog(mockHttp); diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index 9d02d20778..a577c97e31 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -40,11 +40,11 @@ public class QnAMakerTests public AdaptiveDialog QnAMakerAction_ActiveLearningDialogBase() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetTrainRequestUrl()) .Respond(HttpStatusCode.NoContent, "application/json", "{ }"); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json")); return CreateQnAMakerActionDialog(mockHttp); } @@ -143,9 +143,9 @@ await CreateFlow(rootDialog) public AdaptiveDialog QnAMakerAction_MultiTurnDialogBase() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"I have issues related to KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"I have issues related to KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnAnswer_withPrompts.json")); - mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Accidently deleted KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":27,\"previousUserQuery\":\"\"},\"qnaId\":1,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":null}") + mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Accidently deleted KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":27,\"previousUserQuery\":\"\"},\"qnaId\":1,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnAnswer_MultiTurnLevel1.json")); return CreateQnAMakerActionDialog(mockHttp); @@ -157,7 +157,7 @@ public async Task QnAMakerAction_MultiTurnDialogBase_WithAnswer() var rootDialog = QnAMakerAction_MultiTurnDialogBase(); var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json"))); - var promptsActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true, CancellationToken.None); + var promptsActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true); var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); await CreateFlow(rootDialog) @@ -174,7 +174,7 @@ public async Task QnAMakerAction_MultiTurnDialogBase_WithNoAnswer() var rootDialog = QnAMakerAction_MultiTurnDialogBase(); var response = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json"))); - var promptsActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true, CancellationToken.None); + var promptsActivity = QnACardBuilder.GetQnADefaultResponse(response.Answers[0], true); var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer(); await CreateFlow(rootDialog) From 00e5d699443a3b3ebcc83faa9dd789ef62ed0e8c Mon Sep 17 00:00:00 2001 From: vipeketi Date: Wed, 17 Jun 2020 00:29:01 +0530 Subject: [PATCH 56/60] Undo contenttype change. --- libraries/Microsoft.Bot.Schema/ContentTypes.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libraries/Microsoft.Bot.Schema/ContentTypes.cs b/libraries/Microsoft.Bot.Schema/ContentTypes.cs index cb0f1e818f..63a90a5556 100644 --- a/libraries/Microsoft.Bot.Schema/ContentTypes.cs +++ b/libraries/Microsoft.Bot.Schema/ContentTypes.cs @@ -23,10 +23,6 @@ public partial class HeroCard { public const string ContentType = "application/vnd.microsoft.card.hero"; - public static explicit operator HeroCard(Attachment v) - { - throw new NotImplementedException(); - } } /// From 946c4b7c3b145e6e568ba8990cfb4d1bb43b5844 Mon Sep 17 00:00:00 2001 From: vipeketi Date: Wed, 17 Jun 2020 00:33:31 +0530 Subject: [PATCH 57/60] format --- libraries/Microsoft.Bot.Schema/ContentTypes.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/Microsoft.Bot.Schema/ContentTypes.cs b/libraries/Microsoft.Bot.Schema/ContentTypes.cs index 63a90a5556..8065ff9a29 100644 --- a/libraries/Microsoft.Bot.Schema/ContentTypes.cs +++ b/libraries/Microsoft.Bot.Schema/ContentTypes.cs @@ -22,7 +22,6 @@ public partial class ThumbnailCard public partial class HeroCard { public const string ContentType = "application/vnd.microsoft.card.hero"; - } /// From b98c43cda6c48f1fed48435a56b369fc331db99e Mon Sep 17 00:00:00 2001 From: vipeketi Date: Wed, 17 Jun 2020 20:42:00 +0530 Subject: [PATCH 58/60] Final Commit --- .../AnswerSpanRequest.cs | 3 +- .../Dialogs/QnAMakerDialog.cs | 9 +- .../Models/QnAMakerTraceInfo.cs | 5 +- .../Models/QueryResult.cs | 4 +- .../QnAMakerOptions.cs | 4 +- .../QnAMakerRecognizer.cs | 19 +- .../Microsoft.QnAMakerRecognizer.schema | 267 +++++++++--------- .../Utils/QnACardBuilder.cs | 10 +- .../Microsoft.Bot.Schema/ContentTypes.cs | 1 - .../QnAMakerRecognizerTests.cs | 8 +- 10 files changed, 169 insertions(+), 161 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs index 69add0fb9f..f2f6235a50 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/AnswerSpanRequest.cs @@ -11,8 +11,7 @@ namespace Microsoft.Bot.Builder.AI.QnA public class AnswerSpanRequest { /// - /// Gets or sets a value indicating whether to enable PreciseAnswer generation or not. User can choose to use this feature of QnAMaker - /// Service using this configuration. + /// Gets or sets a value indicating whether to enable PreciseAnswer generation. /// /// /// Choice whether to generate precise answer or not. diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs index 573163b79c..b07bc39293 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Dialogs/QnAMakerDialog.cs @@ -294,7 +294,7 @@ public QnAMakerDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNu /// Gets or sets a value indicating whether to enable PreciseAnswer generation. /// /// - /// A value indicating user's choice between precise answer and full text in response to QnAMaker GenerateAnswer query. + /// Choice whether to generate precise answer or not. /// [JsonProperty("enablePreciseAnswer")] public BoolExpression EnablePreciseAnswer { get; set; } = false; @@ -656,13 +656,6 @@ private async Task CheckForMultiTurnPromptAsync(WaterfallStepC return await stepContext.NextAsync(stepContext.Result, cancellationToken).ConfigureAwait(false); } - /// - /// Gets the options the dialog will use to display query results to the user. - /// - /// The for the current turn of conversation. - /// The for the current turn of conversation. - /// A representing the asynchronous operation. - /// If the task is successful, the result contains the as per user's choice. private async Task DisplayQnAResultAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var dialogOptions = ObjectPath.GetPathValue(stepContext.ActiveDialog.State, Options); diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs index 264963da49..3bb7b817be 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QnAMakerTraceInfo.cs @@ -109,10 +109,11 @@ public class QnAMakerTraceInfo public Metadata[] MetadataBoost { get; set; } /// - /// Gets or sets AnswerSpanRequest of the previous turn. + /// Gets or sets AnswerSpanRequest. + /// Users can request PreciseAnswer from QnAMaker using this configuration. /// /// - /// The AnswerSpanRequest. + /// AnswerSpanRequest for requesting PreciseAnswer. /// [JsonProperty("answerSpanRequest")] public AnswerSpanRequest AnswerSpanRequest { get; set; } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs index eecca1c126..4f26203beb 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Models/QueryResult.cs @@ -78,10 +78,10 @@ public class QueryResult public QnAResponseContext Context { get; set; } /// - /// Gets or sets AnswerSpan of the previous turn. + /// Gets or sets details of PreciseAnswer. /// /// - /// The answerspan value. + /// The PreciseAnswer related information in the Answer Text. /// [JsonProperty("answerSpan")] public AnswerSpanResponse AnswerSpan { get; set; } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs index 6003522ad7..e7b8e0d70f 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerOptions.cs @@ -94,10 +94,10 @@ public QnAMakerOptions() public string RankerType { get; set; } /// - /// Gets or sets a value indicating whether Precise Answer needs to be provided from source text or not. + /// Gets or sets a value indicating whether to enable PreciseAnswer generation. /// /// - /// To enable Precise Answer or not. + /// Choice whether to generate precise answer or not. /// [JsonProperty("enablePreciseAnswer")] public bool EnablePreciseAnswer { get; set; } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs index 5696a494a5..a54ba96dde 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/QnAMakerRecognizer.cs @@ -140,6 +140,15 @@ public QnAMakerRecognizer() [JsonProperty("logPersonalInformation")] public BoolExpression LogPersonalInformation { get; set; } = "=settings.telemetry.logPersonalInformation"; + /// + /// Gets or sets a value indicating whether to enable PreciseAnswer generation. + /// + /// + /// Choice whether to generate precise answer or not. + /// + [JsonProperty("enablePreciseAnswer")] + public BoolExpression EnablePreciseAnswer { get; set; } = false; + public override async Task RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken, Dictionary telemetryProperties = null, Dictionary telemetryMetrics = null) { // Identify matched intents @@ -180,7 +189,8 @@ public override async Task RecognizeAsync(DialogContext dialog Top = this.Top.GetValue(dialogContext.State), QnAId = this.QnAId.GetValue(dialogContext.State), RankerType = this.RankerType.GetValue(dialogContext.State), - IsTest = this.IsTest + IsTest = this.IsTest, + EnablePreciseAnswer = this.EnablePreciseAnswer.GetValue(dialogContext.State) }, null).ConfigureAwait(false); @@ -208,6 +218,13 @@ public override async Task RecognizeAsync(DialogContext dialog answerArray.Add(topAnswer.Answer); ObjectPath.SetPathValue(recognizerResult, "entities.answer", answerArray); + if (!string.IsNullOrEmpty(topAnswer.AnswerSpan?.Text)) + { + var answerSpanArray = new JArray(); + answerSpanArray.Add(topAnswer.AnswerSpan.Text); + ObjectPath.SetPathValue(recognizerResult, "entities.answerspan", answerSpanArray); + } + var instance = new JArray(); instance.Add(JObject.FromObject(topAnswer)); ObjectPath.SetPathValue(recognizerResult, "entities.$instance.answer", instance); diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerRecognizer.schema b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerRecognizer.schema index e87a9344fa..20732935f0 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerRecognizer.schema +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerRecognizer.schema @@ -4,141 +4,146 @@ "title": "QnAMaker Recognizer", "description": "Recognizer for generating QnAMatch intents from a KB.", "type": "object", - "properties": { - "id": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "Optional unique id using with RecognizerSet." + }, + "knowledgeBaseId": { + "$ref": "schema:#/definitions/stringExpression", + "title": "KnowledgeBase Id", + "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", + "default": "settings.qna.knowledgebaseid" + }, + "endpointKey": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Endpoint Key", + "description": "Endpoint key for the QnA Maker KB.", + "default": "settings.qna.endpointkey" + }, + "hostname": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Hostname", + "description": "Hostname for your QnA Maker service.", + "default": "settings.qna.hostname", + "examples": [ + "https://yourserver.azurewebsites.net/qnamaker" + ] + }, + "threshold": { + "$ref": "schema:#/definitions/numberExpression", + "title": "Threshold", + "description": "Threshold score to filter results.", + "default": 0.3 + }, + "strictFilters": { + "$ref": "schema:#/definitions/arrayExpression", + "title": "Strict Filters", + "description": "Metadata filters to use when calling the QnA Maker KB.", + "items": { + "type": "object", + "title": "Metadata filters", + "description": "Metadata filters to use when querying QnA Maker KB.", + "properties": { + "name": { "type": "string", - "title": "Id", - "description": "Optional unique id using with RecognizerSet." - }, - "knowledgeBaseId": { - "$ref": "schema:#/definitions/stringExpression", - "title": "KnowledgeBase Id", - "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", - "default": "settings.qna.knowledgebaseid" - }, - "endpointKey": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Endpoint Key", - "description": "Endpoint key for the QnA Maker KB.", - "default": "settings.qna.endpointkey" - }, - "hostname": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Hostname", - "description": "Hostname for your QnA Maker service.", - "default": "settings.qna.hostname", - "examples": [ - "https://yourserver.azurewebsites.net/qnamaker" - ] - }, - "threshold": { - "$ref": "schema:#/definitions/numberExpression", - "title": "Threshold", - "description": "Threshold score to filter results.", - "default": 0.3 - }, - "strictFilters": { - "$ref": "schema:#/definitions/arrayExpression", - "title": "Strict Filters", - "description": "Metadata filters to use when calling the QnA Maker KB.", - "items": { - "type": "object", - "title": "Metadata filters", - "description": "Metadata filters to use when querying QnA Maker KB.", - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "Name to filter on.", - "maximum": 100 - }, - "value": { - "type": "string", - "title": "Value", - "description": "Value to restrict filter.", - "maximum": 100 - } - } - } - }, - "top": { - "$ref": "schema:#/definitions/numberExpression", - "title": "Top", - "description": "The number of answers you want to retrieve.", - "default": 3 - }, - "isTest": { - "$ref": "schema:#/definitions/booleanExpression", - "title": "IsTest", - "description": "True, if pointing to Test environment, else false.", - "examples": [ - true, - "=f(x)" - ] - }, - "rankerType": { - "title": "Ranker Type", - "description": "Type of Ranker.", - "oneOf": [ - { - "type": "string", - "title": "Ranker type", - "description": "Type of Ranker.", - "enum": [ - "default", - "questionOnly", - "autoSuggestQuestion" - ], - "default": "default" - }, - { - "$ref": "schema:#/definitions/equalsExpression" - } - ] - }, - "includeDialogNameInMetadata": { - "$ref": "schema:#/definitions/booleanExpression", - "title": "Include Dialog Name", - "description": "When set to false, the dialog name will not be passed to QnAMaker. (default) is true", - "default": true, - "examples": [ - true, - "=f(x)" - ] - }, - "metadata": { - "$ref": "schema:#/definitions/arrayExpression", - "title": "Metadata filters", - "description": "Metadata filters to use when calling the QnA Maker KB.", - "items": { - "type": "object", - "title": "Metadata filter", - "description": "Metadata filter to use when calling the QnA Maker KB.", - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "Name of value to test." - }, - "value": { - "type": "string", - "title": "Value", - "description": "Value to filter against." - } - } - } - }, - "context": { - "$ref": "schema:#/definitions/objectExpression", - "title": "QnARequestContext", - "description": "Context to use for ranking." + "title": "Name", + "description": "Name to filter on.", + "maximum": 100 + }, + "value": { + "type": "string", + "title": "Value", + "description": "Value to restrict filter.", + "maximum": 100 + } + } + } + }, + "top": { + "$ref": "schema:#/definitions/numberExpression", + "title": "Top", + "description": "The number of answers you want to retrieve.", + "default": 3 + }, + "isTest": { + "$ref": "schema:#/definitions/booleanExpression", + "title": "IsTest", + "description": "True, if pointing to Test environment, else false.", + "examples": [ + true, + "=f(x)" + ] + }, + "rankerType": { + "title": "Ranker Type", + "description": "Type of Ranker.", + "oneOf": [ + { + "type": "string", + "title": "Ranker type", + "description": "Type of Ranker.", + "enum": [ + "default", + "questionOnly", + "autoSuggestQuestion" + ], + "default": "default" }, - "qnaId": { - "$ref": "schema:#/definitions/integerExpression", - "title": "QnAId", - "description": "A number or expression which is the QnAId to paass to QnAMaker API." + { + "$ref": "schema:#/definitions/equalsExpression" } + ] + }, + "includeDialogNameInMetadata": { + "$ref": "schema:#/definitions/booleanExpression", + "title": "Include Dialog Name", + "description": "When set to false, the dialog name will not be passed to QnAMaker. (default) is true", + "default": true, + "examples": [ + true, + "=f(x)" + ] + }, + "metadata": { + "$ref": "schema:#/definitions/arrayExpression", + "title": "Metadata filters", + "description": "Metadata filters to use when calling the QnA Maker KB.", + "items": { + "type": "object", + "title": "Metadata filter", + "description": "Metadata filter to use when calling the QnA Maker KB.", + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "Name of value to test." + }, + "value": { + "type": "string", + "title": "Value", + "description": "Value to filter against." + } + } + } + }, + "context": { + "$ref": "schema:#/definitions/objectExpression", + "title": "QnARequestContext", + "description": "Context to use for ranking." + }, + "qnaId": { + "$ref": "schema:#/definitions/integerExpression", + "title": "QnAId", + "description": "A number or expression which is the QnAId to paass to QnAMaker API." }, + "enablePreciseAnswer": { + "$ref": "schema:#/definitions/booleanExpression", + "title": "EnablePreciseAnswer", + "description": "True, if precise answer is opted, else false." + } + }, "required": [ "knowledgeBaseId", "endpointKey", diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs index 74673df54d..57d1939e18 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/QnACardBuilder.cs @@ -90,8 +90,8 @@ public static IMessageActivity GetQnAPromptsCard(QueryResult result, string card /// /// Get Answer Card. /// - /// Result consists of Answer, Precise Answer (Optionally) and References to other answers, also called as Prompts. - /// Parameter to set either of the two choices: 1. Precise answer only 2. Precise answer and corresponding text. + /// Result to be displayed. + /// Choice whether to display Precise Answer Only or source text along with Precise Answer. /// Message activity for Query Result. public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool displayPreciseAnswerOnly) { @@ -107,7 +107,7 @@ public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool di if (result?.Context?.Prompts != null && result.Context.Prompts.Any()) { - // Add all prompt + // Add all prompts foreach (var prompt in result.Context.Prompts) { buttonList.Add( @@ -125,7 +125,7 @@ public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool di { chatActivity.Text = result.AnswerSpan.Text; - // When the configuration is set to display precise answer + // When the configuration is set to display precise answer only if (!displayPreciseAnswerOnly) { heroCardText = result.Answer; @@ -134,7 +134,7 @@ public static IMessageActivity GetQnADefaultResponse(QueryResult result, bool di if (buttonList.Any() || !string.IsNullOrWhiteSpace(heroCardText)) { - var plCard = new HeroCard(); + var plCard = new HeroCard(); if (buttonList.Any()) { diff --git a/libraries/Microsoft.Bot.Schema/ContentTypes.cs b/libraries/Microsoft.Bot.Schema/ContentTypes.cs index 8065ff9a29..aefbae5f01 100644 --- a/libraries/Microsoft.Bot.Schema/ContentTypes.cs +++ b/libraries/Microsoft.Bot.Schema/ContentTypes.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; using System.Diagnostics.CodeAnalysis; namespace Microsoft.Bot.Schema diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs index 41e4d647ff..5da0a7402f 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs @@ -60,13 +60,7 @@ public AdaptiveDialog QnAMakerRecognizer_DialogBase() var mockHttp = new MockHttpMessageHandler(); mockHttp.When(HttpMethod.Post, GetRequestUrl()) .WithContent("{\"question\":\"QnaMaker_ReturnsAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") - .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer.json")); - mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") - .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); - mockHttp.When(HttpMethod.Post, GetRequestUrl()) - .WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") - .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); + .Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()) .WithContent("{\"question\":\"QnaMaker_ReturnsNoAnswer\",\"top\":3,\"strictFilters\":[{\"name\":\"dialogName\",\"value\":\"outer\"}],\"scoreThreshold\":0.3,\"context\":null,\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnsNoAnswer.json")); From b23c2936a098978b14b82c1204e1fe73b1edca4e Mon Sep 17 00:00:00 2001 From: vipeketi Date: Wed, 17 Jun 2020 21:28:58 +0530 Subject: [PATCH 59/60] Spaces formating. --- .../Schemas/Microsoft.QnAMakerDialog.schema | 24 +++++++++---------- .../Utils/GenerateAnswerUtils.cs | 2 +- .../QnAMakerTests.cs | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema index 0ba17d8faa..082ee755f3 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema @@ -1,10 +1,10 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/botframework-sdk/master/schemas/component/component.schema", - "$role": "implements(Microsoft.IDialog)", - "title": "QnAMaker Dialog", - "description": "Dialog which uses QnAMAker knowledge base to answer questions.", - "type": "object", - "additionalProperties": false, + "$schema": "https://raw.githubusercontent.com/microsoft/botframework-sdk/master/schemas/component/component.schema", + "$role": "implements(Microsoft.IDialog)", + "title": "QnAMaker Dialog", + "description": "Dialog which uses QnAMAker knowledge base to answer questions.", + "type": "object", + "additionalProperties": false, "properties": { "knowledgeBaseId": { "$ref": "schema:#/definitions/stringExpression", @@ -92,7 +92,7 @@ "title": "IsTest", "description": "True, if pointing to Test environment, else false.", "default": false - }, + }, "enablePreciseAnswer": { "$ref": "schema:#/definitions/booleanExpression", "title": "EnablePreciseAnswer", @@ -124,9 +124,9 @@ ] } }, - "required": [ - "knowledgeBaseId", - "endpointKey", - "hostname" - ] + "required": [ + "knowledgeBaseId", + "endpointKey", + "hostname" + ] } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs index 2996d8dfd5..0cc0088da6 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Utils/GenerateAnswerUtils.cs @@ -142,7 +142,7 @@ private static void ValidateOptions(QnAMakerOptions options) if (options.RankerType == null) { options.RankerType = RankerTypes.DefaultRankerType; - } + } } /// diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index a577c97e31..8053140ed3 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -39,7 +39,7 @@ public class QnAMakerTests public AdaptiveDialog QnAMakerAction_ActiveLearningDialogBase() { - var mockHttp = new MockHttpMessageHandler(); + var mockHttp = new MockHttpMessageHandler(); mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json")); mockHttp.When(HttpMethod.Post, GetTrainRequestUrl()) @@ -142,7 +142,7 @@ await CreateFlow(rootDialog) public AdaptiveDialog QnAMakerAction_MultiTurnDialogBase() { - var mockHttp = new MockHttpMessageHandler(); + var mockHttp = new MockHttpMessageHandler(); mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"I have issues related to KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") .Respond("application/json", GetResponse("QnaMaker_ReturnAnswer_withPrompts.json")); mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Accidently deleted KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":0.3,\"context\":{\"previousQnAId\":27,\"previousUserQuery\":\"\"},\"qnaId\":1,\"isTest\":false,\"rankerType\":\"Default\",\"answerSpanRequest\":{\"enable\":false}}") From c99e7930c7c6032543211677643fbeadd5a9cd83 Mon Sep 17 00:00:00 2001 From: vipeketi Date: Wed, 17 Jun 2020 23:17:32 +0530 Subject: [PATCH 60/60] Indentation for schema files. --- .../Schemas/Microsoft.QnAMakerDialog.schema | 256 ++++++++--------- .../Microsoft.QnAMakerRecognizer.schema | 272 +++++++++--------- 2 files changed, 264 insertions(+), 264 deletions(-) diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema index 082ee755f3..beafb91166 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerDialog.schema @@ -1,132 +1,132 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/botframework-sdk/master/schemas/component/component.schema", - "$role": "implements(Microsoft.IDialog)", - "title": "QnAMaker Dialog", - "description": "Dialog which uses QnAMAker knowledge base to answer questions.", - "type": "object", - "additionalProperties": false, - "properties": { - "knowledgeBaseId": { - "$ref": "schema:#/definitions/stringExpression", - "title": "KnowledgeBase Id", - "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", - "default": "=settings.qna.knowledgebaseid" - }, - "endpointKey": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Endpoint Key", - "description": "Endpoint key for the QnA Maker KB.", - "default": "=settings.qna.endpointkey" - }, - "hostname": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Hostname", - "description": "Hostname for your QnA Maker service.", - "default": "=settings.qna.hostname", - "examples": [ - "https://yourserver.azurewebsites.net/qnamaker" - ] - }, - "noAnswer": { - "$kind": "Microsoft.IActivityTemplate", - "title": "Fallback answer", - "description": "Default answer to return when none found in KB.", - "default": "Sorry, I did not find an answer." - }, - "threshold": { - "$ref": "schema:#/definitions/numberExpression", - "title": "Threshold", - "description": "Threshold score to filter results.", - "default": 0.3 - }, - "activeLearningCardTitle": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Active learning card title", - "description": "Title for active learning suggestions card.", - "default": "Did you mean:" - }, - "cardNoMatchText": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Card no match text", - "description": "Text for no match option.", - "default": "None of the above." - }, - "cardNoMatchResponse": { - "$kind": "Microsoft.IActivityTemplate", - "title": "Card no match response", - "description": "Custom response when no match option was selected.", - "default": "Thanks for the feedback." - }, - "strictFilters": { - "$ref": "schema:#/definitions/arrayExpression", - "title": "Strict Filters", - "description": "Metadata filters to use when calling the QnA Maker KB.", - "items": { - "type": "object", - "title": "Metadata filter", - "description": "Metadata filter.", - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "Name of filter property.", - "maximum": 100 - }, - "value": { - "type": "string", - "title": "Value", - "description": "Value to filter on.", - "maximum": 100 - } - } - } - }, - "top": { - "$ref": "schema:#/definitions/numberExpression", - "title": "Top", - "description": "The number of answers you want to retrieve.", - "default": 3 - }, - "isTest": { - "type": "boolean", - "title": "IsTest", - "description": "True, if pointing to Test environment, else false.", - "default": false - }, - "enablePreciseAnswer": { - "$ref": "schema:#/definitions/booleanExpression", - "title": "EnablePreciseAnswer", - "description": "True, if precise answer is opted, else false." - }, - "displayPreciseAnswerOnly": { - "$ref": "schema:#/definitions/booleanExpression", - "title": "DisplayPreciseAnswerOnly", - "description": "True, if precise answer text only is opted, else false." - }, - "rankerType": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Ranker Type", - "description": "Type of Ranker.", - "oneOf": [ - { - "title": "Standard ranker", - "description": "Standard ranker types.", - "enum": [ - "default", - "questionOnly", - "autoSuggestQuestion" - ], - "default": "default" + "$schema": "https://raw.githubusercontent.com/microsoft/botframework-sdk/master/schemas/component/component.schema", + "$role": "implements(Microsoft.IDialog)", + "title": "QnAMaker Dialog", + "description": "Dialog which uses QnAMAker knowledge base to answer questions.", + "type": "object", + "additionalProperties": false, + "properties": { + "knowledgeBaseId": { + "$ref": "schema:#/definitions/stringExpression", + "title": "KnowledgeBase Id", + "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", + "default": "=settings.qna.knowledgebaseid" + }, + "endpointKey": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Endpoint Key", + "description": "Endpoint key for the QnA Maker KB.", + "default": "=settings.qna.endpointkey" + }, + "hostname": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Hostname", + "description": "Hostname for your QnA Maker service.", + "default": "=settings.qna.hostname", + "examples": [ + "https://yourserver.azurewebsites.net/qnamaker" + ] + }, + "noAnswer": { + "$kind": "Microsoft.IActivityTemplate", + "title": "Fallback answer", + "description": "Default answer to return when none found in KB.", + "default": "Sorry, I did not find an answer." + }, + "threshold": { + "$ref": "schema:#/definitions/numberExpression", + "title": "Threshold", + "description": "Threshold score to filter results.", + "default": 0.3 + }, + "activeLearningCardTitle": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Active learning card title", + "description": "Title for active learning suggestions card.", + "default": "Did you mean:" + }, + "cardNoMatchText": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Card no match text", + "description": "Text for no match option.", + "default": "None of the above." }, - { - "$ref": "schema:#/definitions/equalsExpression" + "cardNoMatchResponse": { + "$kind": "Microsoft.IActivityTemplate", + "title": "Card no match response", + "description": "Custom response when no match option was selected.", + "default": "Thanks for the feedback." + }, + "strictFilters": { + "$ref": "schema:#/definitions/arrayExpression", + "title": "Strict Filters", + "description": "Metadata filters to use when calling the QnA Maker KB.", + "items": { + "type": "object", + "title": "Metadata filter", + "description": "Metadata filter.", + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "Name of filter property.", + "maximum": 100 + }, + "value": { + "type": "string", + "title": "Value", + "description": "Value to filter on.", + "maximum": 100 + } + } + } + }, + "top": { + "$ref": "schema:#/definitions/numberExpression", + "title": "Top", + "description": "The number of answers you want to retrieve.", + "default": 3 + }, + "isTest": { + "type": "boolean", + "title": "IsTest", + "description": "True, if pointing to Test environment, else false.", + "default": false + }, + "enablePreciseAnswer": { + "$ref": "schema:#/definitions/booleanExpression", + "title": "EnablePreciseAnswer", + "description": "True, if PreciseAnswer is opted, else false." + }, + "displayPreciseAnswerOnly": { + "$ref": "schema:#/definitions/booleanExpression", + "title": "DisplayPreciseAnswerOnly", + "description": "True, if PreciseAnswer text only is opted, else false." + }, + "rankerType": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Ranker Type", + "description": "Type of Ranker.", + "oneOf": [ + { + "title": "Standard ranker", + "description": "Standard ranker types.", + "enum": [ + "default", + "questionOnly", + "autoSuggestQuestion" + ], + "default": "default" + }, + { + "$ref": "schema:#/definitions/equalsExpression" + } + ] } - ] - } - }, - "required": [ - "knowledgeBaseId", - "endpointKey", - "hostname" - ] + }, + "required": [ + "knowledgeBaseId", + "endpointKey", + "hostname" + ] } diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerRecognizer.schema b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerRecognizer.schema index 20732935f0..56aac1e045 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerRecognizer.schema +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Schemas/Microsoft.QnAMakerRecognizer.schema @@ -4,146 +4,146 @@ "title": "QnAMaker Recognizer", "description": "Recognizer for generating QnAMatch intents from a KB.", "type": "object", - "properties": { - "id": { - "type": "string", - "title": "Id", - "description": "Optional unique id using with RecognizerSet." - }, - "knowledgeBaseId": { - "$ref": "schema:#/definitions/stringExpression", - "title": "KnowledgeBase Id", - "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", - "default": "settings.qna.knowledgebaseid" - }, - "endpointKey": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Endpoint Key", - "description": "Endpoint key for the QnA Maker KB.", - "default": "settings.qna.endpointkey" - }, - "hostname": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Hostname", - "description": "Hostname for your QnA Maker service.", - "default": "settings.qna.hostname", - "examples": [ - "https://yourserver.azurewebsites.net/qnamaker" - ] - }, - "threshold": { - "$ref": "schema:#/definitions/numberExpression", - "title": "Threshold", - "description": "Threshold score to filter results.", - "default": 0.3 - }, - "strictFilters": { - "$ref": "schema:#/definitions/arrayExpression", - "title": "Strict Filters", - "description": "Metadata filters to use when calling the QnA Maker KB.", - "items": { - "type": "object", - "title": "Metadata filters", - "description": "Metadata filters to use when querying QnA Maker KB.", - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "Name to filter on.", - "maximum": 100 - }, - "value": { + "properties": { + "id": { "type": "string", - "title": "Value", - "description": "Value to restrict filter.", - "maximum": 100 - } - } - } - }, - "top": { - "$ref": "schema:#/definitions/numberExpression", - "title": "Top", - "description": "The number of answers you want to retrieve.", - "default": 3 - }, - "isTest": { - "$ref": "schema:#/definitions/booleanExpression", - "title": "IsTest", - "description": "True, if pointing to Test environment, else false.", - "examples": [ - true, - "=f(x)" - ] - }, - "rankerType": { - "title": "Ranker Type", - "description": "Type of Ranker.", - "oneOf": [ - { - "type": "string", - "title": "Ranker type", - "description": "Type of Ranker.", - "enum": [ - "default", - "questionOnly", - "autoSuggestQuestion" - ], - "default": "default" + "title": "Id", + "description": "Optional unique id using with RecognizerSet." }, - { - "$ref": "schema:#/definitions/equalsExpression" - } - ] - }, - "includeDialogNameInMetadata": { - "$ref": "schema:#/definitions/booleanExpression", - "title": "Include Dialog Name", - "description": "When set to false, the dialog name will not be passed to QnAMaker. (default) is true", - "default": true, - "examples": [ - true, - "=f(x)" - ] - }, - "metadata": { - "$ref": "schema:#/definitions/arrayExpression", - "title": "Metadata filters", - "description": "Metadata filters to use when calling the QnA Maker KB.", - "items": { - "type": "object", - "title": "Metadata filter", - "description": "Metadata filter to use when calling the QnA Maker KB.", - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "Name of value to test." - }, - "value": { - "type": "string", - "title": "Value", - "description": "Value to filter against." - } + "knowledgeBaseId": { + "$ref": "schema:#/definitions/stringExpression", + "title": "KnowledgeBase Id", + "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", + "default": "settings.qna.knowledgebaseid" + }, + "endpointKey": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Endpoint Key", + "description": "Endpoint key for the QnA Maker KB.", + "default": "settings.qna.endpointkey" + }, + "hostname": { + "$ref": "schema:#/definitions/stringExpression", + "title": "Hostname", + "description": "Hostname for your QnA Maker service.", + "default": "settings.qna.hostname", + "examples": [ + "https://yourserver.azurewebsites.net/qnamaker" + ] + }, + "threshold": { + "$ref": "schema:#/definitions/numberExpression", + "title": "Threshold", + "description": "Threshold score to filter results.", + "default": 0.3 + }, + "strictFilters": { + "$ref": "schema:#/definitions/arrayExpression", + "title": "Strict Filters", + "description": "Metadata filters to use when calling the QnA Maker KB.", + "items": { + "type": "object", + "title": "Metadata filters", + "description": "Metadata filters to use when querying QnA Maker KB.", + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "Name to filter on.", + "maximum": 100 + }, + "value": { + "type": "string", + "title": "Value", + "description": "Value to restrict filter.", + "maximum": 100 + } + } + } + }, + "top": { + "$ref": "schema:#/definitions/numberExpression", + "title": "Top", + "description": "The number of answers you want to retrieve.", + "default": 3 + }, + "isTest": { + "$ref": "schema:#/definitions/booleanExpression", + "title": "IsTest", + "description": "True, if pointing to Test environment, else false.", + "examples": [ + true, + "=f(x)" + ] + }, + "rankerType": { + "title": "Ranker Type", + "description": "Type of Ranker.", + "oneOf": [ + { + "type": "string", + "title": "Ranker type", + "description": "Type of Ranker.", + "enum": [ + "default", + "questionOnly", + "autoSuggestQuestion" + ], + "default": "default" + }, + { + "$ref": "schema:#/definitions/equalsExpression" + } + ] + }, + "includeDialogNameInMetadata": { + "$ref": "schema:#/definitions/booleanExpression", + "title": "Include Dialog Name", + "description": "When set to false, the dialog name will not be passed to QnAMaker. (default) is true", + "default": true, + "examples": [ + true, + "=f(x)" + ] + }, + "metadata": { + "$ref": "schema:#/definitions/arrayExpression", + "title": "Metadata filters", + "description": "Metadata filters to use when calling the QnA Maker KB.", + "items": { + "type": "object", + "title": "Metadata filter", + "description": "Metadata filter to use when calling the QnA Maker KB.", + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "Name of value to test." + }, + "value": { + "type": "string", + "title": "Value", + "description": "Value to filter against." + } + } + } + }, + "context": { + "$ref": "schema:#/definitions/objectExpression", + "title": "QnARequestContext", + "description": "Context to use for ranking." + }, + "qnaId": { + "$ref": "schema:#/definitions/integerExpression", + "title": "QnAId", + "description": "A number or expression which is the QnAId to paass to QnAMaker API." + }, + "enablePreciseAnswer": { + "$ref": "schema:#/definitions/booleanExpression", + "title": "EnablePreciseAnswer", + "description": "True, if PreciseAnswer is opted, else false." } - } - }, - "context": { - "$ref": "schema:#/definitions/objectExpression", - "title": "QnARequestContext", - "description": "Context to use for ranking." - }, - "qnaId": { - "$ref": "schema:#/definitions/integerExpression", - "title": "QnAId", - "description": "A number or expression which is the QnAId to paass to QnAMaker API." }, - "enablePreciseAnswer": { - "$ref": "schema:#/definitions/booleanExpression", - "title": "EnablePreciseAnswer", - "description": "True, if precise answer is opted, else false." - } - }, "required": [ "knowledgeBaseId", "endpointKey",