Add support for Teams Adaptive cards in QnA Dialog (#6625)
* Update QnaMakerDialog.cs to add new bool parameter * Add adaptive card implementation * Add new parameter to GetQnADefaulTResponse calls * Add comments and check for empty text * Clean up code, update comments, update method names * Address requested changes * Add versions of tests for QnAMakerDialog that use Adaptive Card implementation Tests passing on branch code. --------- Co-authored-by: Anish Prasad <v-aniprasad@microsoft.com>
This commit is contained in:
Родитель
11597ca9af
Коммит
68e0c421d2
|
@ -102,6 +102,7 @@ namespace Microsoft.Bot.Builder.AI.QnA.Dialogs
|
|||
/// of the source file that contains the caller.</param>
|
||||
/// <param name="sourceLineNumber">The line number, for debugging. Defaults to the line number
|
||||
/// in the source file at which the method is called.</param>
|
||||
/// <param name="useTeamsAdaptiveCard"> Boolean value to determine whether an Adaptive card formatted for Teams should be used for responses.</param>
|
||||
public QnAMakerDialog(
|
||||
string dialogId,
|
||||
string knowledgeBaseId,
|
||||
|
@ -118,7 +119,8 @@ namespace Microsoft.Bot.Builder.AI.QnA.Dialogs
|
|||
ServiceType qnAServiceType = ServiceType.QnAMaker,
|
||||
HttpClient httpClient = null,
|
||||
[CallerFilePath] string sourceFilePath = "",
|
||||
[CallerLineNumber] int sourceLineNumber = 0)
|
||||
[CallerLineNumber] int sourceLineNumber = 0,
|
||||
bool useTeamsAdaptiveCard = false)
|
||||
: base(dialogId)
|
||||
{
|
||||
this.RegisterSourceLocation(sourceFilePath, sourceLineNumber);
|
||||
|
@ -135,6 +137,7 @@ namespace Microsoft.Bot.Builder.AI.QnA.Dialogs
|
|||
Filters = filters;
|
||||
QnAServiceType = qnAServiceType;
|
||||
this.HttpClient = httpClient;
|
||||
this.UseTeamsAdaptiveCard = useTeamsAdaptiveCard;
|
||||
|
||||
// add waterfall steps
|
||||
this.AddStep(CallGenerateAnswerAsync);
|
||||
|
@ -169,6 +172,7 @@ namespace Microsoft.Bot.Builder.AI.QnA.Dialogs
|
|||
/// of the source file that contains the caller.</param>
|
||||
/// <param name="sourceLineNumber">The line number, for debugging. Defaults to the line number
|
||||
/// in the source file at which the method is called.</param>
|
||||
/// <param name="useTeamsAdaptiveCard"> Boolean value to determine whether an Adaptive card formatted for Teams should be used for responses.</param>
|
||||
public QnAMakerDialog(
|
||||
string knowledgeBaseId,
|
||||
string endpointKey,
|
||||
|
@ -184,7 +188,8 @@ namespace Microsoft.Bot.Builder.AI.QnA.Dialogs
|
|||
ServiceType qnAServiceType = ServiceType.QnAMaker,
|
||||
HttpClient httpClient = null,
|
||||
[CallerFilePath] string sourceFilePath = "",
|
||||
[CallerLineNumber] int sourceLineNumber = 0)
|
||||
[CallerLineNumber] int sourceLineNumber = 0,
|
||||
bool useTeamsAdaptiveCard = false)
|
||||
: this(
|
||||
nameof(QnAMakerDialog),
|
||||
knowledgeBaseId,
|
||||
|
@ -201,7 +206,8 @@ namespace Microsoft.Bot.Builder.AI.QnA.Dialogs
|
|||
qnAServiceType,
|
||||
httpClient,
|
||||
sourceFilePath,
|
||||
sourceLineNumber)
|
||||
sourceLineNumber,
|
||||
useTeamsAdaptiveCard)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -395,6 +401,15 @@ namespace Microsoft.Bot.Builder.AI.QnA.Dialogs
|
|||
[JsonProperty("displayPreciseAnswerOnly")]
|
||||
public BoolExpression DisplayPreciseAnswerOnly { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the dialog response should use a MS Teams formatted Adaptive Card instead of a Hero Card.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// True/False, defaults to False.
|
||||
/// </value>
|
||||
[JsonProperty("useTeamsAdaptiveCard")]
|
||||
public BoolExpression UseTeamsAdaptiveCard { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets QnA Service type to query either QnAMaker or Custom Question Answering Knowledge Base.
|
||||
/// </summary>
|
||||
|
@ -614,7 +629,7 @@ namespace Microsoft.Bot.Builder.AI.QnA.Dialogs
|
|||
var response = (List<QueryResult>)stepContext.Result;
|
||||
if (response.Count > 0 && response[0].Id != -1)
|
||||
{
|
||||
var message = QnACardBuilder.GetQnADefaultResponse(response.First(), dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly);
|
||||
var message = QnACardBuilder.GetQnADefaultResponse(response.First(), dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly, UseTeamsAdaptiveCard);
|
||||
await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
|
@ -629,7 +644,7 @@ namespace Microsoft.Bot.Builder.AI.QnA.Dialogs
|
|||
if (response.Count == 1 && response[0].Id == -1)
|
||||
{
|
||||
// Nomatch Response from service.
|
||||
var message = QnACardBuilder.GetQnADefaultResponse(response.First(), dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly);
|
||||
var message = QnACardBuilder.GetQnADefaultResponse(response.First(), dialogOptions.ResponseOptions.DisplayPreciseAnswerOnly, UseTeamsAdaptiveCard);
|
||||
await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
|
@ -839,7 +854,7 @@ namespace Microsoft.Bot.Builder.AI.QnA.Dialogs
|
|||
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, UseTeamsAdaptiveCard);
|
||||
await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false);
|
||||
|
||||
return new DialogTurnResult(DialogTurnStatus.Waiting);
|
||||
|
|
|
@ -94,8 +94,9 @@ namespace Microsoft.Bot.Builder.AI.QnA
|
|||
/// </summary>
|
||||
/// <param name="result">Result to be dispalyed as prompts.</param>
|
||||
/// <param name="displayPreciseAnswerOnly">Choice to render precise answer.</param>
|
||||
/// <param name="useTeamsAdaptiveCard">Choose whether to use a Teams-formatted Adaptive card.</param>
|
||||
/// <returns>IMessageActivity.</returns>
|
||||
public static IMessageActivity GetQnADefaultResponse(QueryResult result, BoolExpression displayPreciseAnswerOnly)
|
||||
public static IMessageActivity GetQnADefaultResponse(QueryResult result, BoolExpression displayPreciseAnswerOnly, BoolExpression useTeamsAdaptiveCard = null)
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
|
@ -126,7 +127,7 @@ namespace Microsoft.Bot.Builder.AI.QnA
|
|||
}
|
||||
}
|
||||
|
||||
string heroCardText = null;
|
||||
string cardText = null;
|
||||
if (!string.IsNullOrWhiteSpace(result?.AnswerSpan?.Text))
|
||||
{
|
||||
chatActivity.Text = result.AnswerSpan.Text;
|
||||
|
@ -134,31 +135,122 @@ namespace Microsoft.Bot.Builder.AI.QnA
|
|||
// For content choice Precise only
|
||||
if (displayPreciseAnswerOnly.Value == false)
|
||||
{
|
||||
heroCardText = result.Answer;
|
||||
cardText = result.Answer;
|
||||
}
|
||||
}
|
||||
|
||||
if (buttonList != null || !string.IsNullOrWhiteSpace(heroCardText))
|
||||
if (buttonList != null || !string.IsNullOrWhiteSpace(cardText))
|
||||
{
|
||||
var plCard = new HeroCard();
|
||||
var useAdaptive = useTeamsAdaptiveCard == null ? false : useTeamsAdaptiveCard.Value;
|
||||
var cardAttachment = useAdaptive ? CreateAdaptiveCardAttachment(cardText, buttonList) : CreateHeroCardAttachment(cardText, buttonList);
|
||||
|
||||
if (buttonList != null)
|
||||
{
|
||||
plCard.Buttons = buttonList;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(heroCardText))
|
||||
{
|
||||
plCard.Text = heroCardText;
|
||||
}
|
||||
|
||||
// Create the attachment.
|
||||
var attachment = plCard.ToAttachment();
|
||||
|
||||
chatActivity.Attachments.Add(attachment);
|
||||
chatActivity.Attachments.Add(cardAttachment);
|
||||
}
|
||||
|
||||
return chatActivity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a Teams-formatted Adaptive Card as Attachment to be returned in the QnA response. Max width and height of response are controlled by Teams.
|
||||
/// </summary>
|
||||
/// <param name="cardText">String of text to be added to the card.</param>
|
||||
/// <param name="buttonList">List of CardAction representing buttons to be added to the card.</param>
|
||||
/// <returns>Attachment.</returns>
|
||||
private static Attachment CreateAdaptiveCardAttachment(string cardText, List<CardAction> buttonList)
|
||||
{
|
||||
// If there are buttons, create an array of buttons for the card.
|
||||
// Each button is represented by a Dictionary containing the required fields for each button.
|
||||
var cardButtons = buttonList?.Select(button =>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "type", "Action.Submit" },
|
||||
{ "title", button.Title },
|
||||
{
|
||||
"data",
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{
|
||||
"msteams",
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "type", "messageBack" },
|
||||
{ "displayText", button.DisplayText },
|
||||
{ "text", button.Text },
|
||||
{ "value", button.Value }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).ToArray();
|
||||
|
||||
// Create a dictionary to represent the completed Adaptive card
|
||||
// msteams field is also a dictionary
|
||||
// body field is an array containing a dictionary
|
||||
var card = new Dictionary<string, object>
|
||||
{
|
||||
{ "$schema", "http://adaptivecards.io/schemas/adaptive-card.json" },
|
||||
{ "type", "AdaptiveCard" },
|
||||
{ "version", "1.3" },
|
||||
{
|
||||
"msteams",
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "width", "full" },
|
||||
{ "height", "full" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"body",
|
||||
new Dictionary<string, string>[]
|
||||
{
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "type", "TextBlock" },
|
||||
{ "text", (!string.IsNullOrWhiteSpace(cardText) ? cardText : string.Empty) }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// If there are buttons, add the buttons array to the card. "actions" must be formatted as an array.
|
||||
if (cardButtons != null)
|
||||
{
|
||||
card.Add("actions", cardButtons);
|
||||
}
|
||||
|
||||
// Create and return the card as an attachment
|
||||
var adaptiveCard = new Attachment()
|
||||
{
|
||||
ContentType = "application/vnd.microsoft.card.adaptive",
|
||||
Content = card
|
||||
};
|
||||
|
||||
return adaptiveCard;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a Hero Card as Attachment to be returned in the QnA response.
|
||||
/// </summary>
|
||||
/// <param name="cardText">string of text to be added to the card.</param>
|
||||
/// <param name="buttonList">List of CardAction representing buttons to be added to the card.</param>
|
||||
/// <returns>Attachment.</returns>
|
||||
private static Attachment CreateHeroCardAttachment(string cardText, List<CardAction> buttonList)
|
||||
{
|
||||
// Create a new hero card, add the text and buttons if they exist
|
||||
var card = new HeroCard();
|
||||
|
||||
if (buttonList != null)
|
||||
{
|
||||
card.Buttons = buttonList;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(cardText))
|
||||
{
|
||||
card.Text = cardText;
|
||||
}
|
||||
|
||||
// Return the card as an attachment
|
||||
return card.ToAttachment();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -189,6 +189,145 @@ namespace Microsoft.Bot.Builder.AI.Tests
|
|||
.StartTestAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The QnAMakerAction_ActiveLearningDialogBase_AdaptiveCard. Tests QnAMakerDialog with Adaptive Cards.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="AdaptiveDialog"/>.</returns>
|
||||
public AdaptiveDialog QnAMakerAction_ActiveLearningDialogBase_AdaptiveCard()
|
||||
{
|
||||
var mockHttp = new MockHttpMessageHandler();
|
||||
mockHttp.When(HttpMethod.Post, GetTrainRequestUrl())
|
||||
.Respond(HttpStatusCode.NoContent, "application/json", "{ }");
|
||||
mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q12\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":30.0,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"StrictFiltersCompoundOperationType\":0}")
|
||||
.Respond("application/json", GetResponse("QnaMaker_ReturnsAnswer_WhenNoAnswerFoundInKb.json"));
|
||||
mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Q11\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":30.0,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"StrictFiltersCompoundOperationType\":0}")
|
||||
.Respond("application/json", GetResponse("QnaMaker_TopNAnswer.json"));
|
||||
return CreateQnAMakerActionDialog_AdaptiveCard(mockHttp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The QnAMakerAction_ActiveLearningDialog_WithProperResponse_AdaptiveCard. Tests QnAMakerDialog with Adaptive Cards.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="Task"/>.</returns>
|
||||
[Fact]
|
||||
public async Task QnAMakerAction_ActiveLearningDialog_WithProperResponse_AdaptiveCard()
|
||||
{
|
||||
var rootDialog = QnAMakerAction_ActiveLearningDialogBase_AdaptiveCard();
|
||||
|
||||
var suggestionList = new List<string> { "Q1", "Q2", "Q3" };
|
||||
var suggestionActivity = QnACardBuilder.GetSuggestionsCard(suggestionList, "Did you mean:", "None of the above.");
|
||||
var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer();
|
||||
|
||||
await CreateFlow(rootDialog, "QnAMakerAction_ActiveLearningDialog_WithProperResponse")
|
||||
.Send("Q11")
|
||||
.AssertReply(suggestionActivity, equalityComparer: qnAMakerCardEqualityComparer)
|
||||
.Send("Q1")
|
||||
.AssertReply("A1")
|
||||
.StartTestAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The QnAMakerAction_ActiveLearningDialog_WithNoResponse_AdaptiveCard. Tests QnAMakerDialog with Adaptive Cards.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="Task"/>.</returns>
|
||||
[Fact]
|
||||
public async Task QnAMakerAction_ActiveLearningDialog_WithNoResponse_AdaptiveCard()
|
||||
{
|
||||
var rootDialog = QnAMakerAction_ActiveLearningDialogBase_AdaptiveCard();
|
||||
|
||||
const string noAnswerActivity = "No match found, please ask another question.";
|
||||
|
||||
var suggestionList = new List<string> { "Q1", "Q2", "Q3" };
|
||||
var suggestionActivity = QnACardBuilder.GetSuggestionsCard(suggestionList, "Did you mean:", "None of the above.");
|
||||
var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer();
|
||||
|
||||
await CreateFlow(rootDialog, "QnAMakerAction_ActiveLearningDialog_WithNoResponse")
|
||||
.Send("Q11")
|
||||
.AssertReply(suggestionActivity, equalityComparer: qnAMakerCardEqualityComparer)
|
||||
.Send("Q12")
|
||||
.AssertReply(noAnswerActivity)
|
||||
.StartTestAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The QnAMakerAction_ActiveLearningDialog_WithNoneOfAboveQuery_AdaptiveCard. Tests QnAMakerDialog with Adaptive Cards.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="Task"/>.</returns>
|
||||
[Fact]
|
||||
public async Task QnAMakerAction_ActiveLearningDialog_WithNoneOfAboveQuery_AdaptiveCard()
|
||||
{
|
||||
var rootDialog = QnAMakerAction_ActiveLearningDialogBase_AdaptiveCard();
|
||||
|
||||
var suggestionList = new List<string> { "Q1", "Q2", "Q3" };
|
||||
var suggestionActivity = QnACardBuilder.GetSuggestionsCard(suggestionList, "Did you mean:", "None of the above.");
|
||||
var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer();
|
||||
|
||||
await CreateFlow(rootDialog, "QnAMakerAction_ActiveLearningDialog_WithNoneOfAboveQuery")
|
||||
.Send("Q11")
|
||||
.AssertReply(suggestionActivity, equalityComparer: qnAMakerCardEqualityComparer)
|
||||
.Send("None of the above.")
|
||||
.AssertReply("Thanks for the feedback.")
|
||||
.StartTestAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The QnAMakerAction_MultiTurnDialogBase_AdaptiveCard. Tests QnAMakerDialog with Adaptive Cards.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="AdaptiveDialog"/>.</returns>
|
||||
public AdaptiveDialog QnAMakerAction_MultiTurnDialogBase_AdaptiveCard()
|
||||
{
|
||||
var mockHttp = new MockHttpMessageHandler();
|
||||
|
||||
mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"I have issues related to KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":30.0,\"context\":{\"previousQnAId\":0,\"previousUserQuery\":\"\"},\"qnaId\":0,\"isTest\":false,\"rankerType\":\"Default\",\"StrictFiltersCompoundOperationType\":0}")
|
||||
.Respond("application/json", GetResponse("QnaMaker_ReturnAnswer_withPrompts.json"));
|
||||
mockHttp.When(HttpMethod.Post, GetRequestUrl()).WithContent("{\"question\":\"Accidently deleted KB\",\"top\":3,\"strictFilters\":[],\"scoreThreshold\":30.0,\"context\":{\"previousQnAId\":27,\"previousUserQuery\":\"\"},\"qnaId\":1,\"isTest\":false,\"rankerType\":\"Default\",\"StrictFiltersCompoundOperationType\":0}")
|
||||
.Respond("application/json", GetResponse("QnaMaker_ReturnAnswer_MultiTurnLevel1.json"));
|
||||
|
||||
return CreateQnAMakerActionDialog_AdaptiveCard(mockHttp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The QnAMakerAction_MultiTurnDialogBase_WithAnswer_AdaptiveCard. Tests QnAMakerDialog with Adaptive Cards.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="Task"/>.</returns>
|
||||
[Fact]
|
||||
public async Task QnAMakerAction_MultiTurnDialogBase_WithAnswer_AdaptiveCard()
|
||||
{
|
||||
var rootDialog = QnAMakerAction_MultiTurnDialogBase_AdaptiveCard();
|
||||
|
||||
var response = JsonConvert.DeserializeObject<QueryResults>(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json")));
|
||||
var promptsActivity = QnACardBuilder.GetQnAPromptsCard(response.Answers[0]);
|
||||
var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer();
|
||||
|
||||
await CreateFlow(rootDialog, nameof(QnAMakerAction_MultiTurnDialogBase_WithAnswer_AdaptiveCard))
|
||||
.Send("I have issues related to KB")
|
||||
.AssertReply(promptsActivity, equalityComparer: qnAMakerCardEqualityComparer)
|
||||
.Send("Accidently deleted KB")
|
||||
.AssertReply("All deletes are permanent, including question and answer pairs, files, URLs, custom questions and answers, knowledge bases, or Azure resources. Make sure you export your knowledge base from the Settings**page before deleting any part of your knowledge base.")
|
||||
.StartTestAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The QnAMakerAction_MultiTurnDialogBase_WithNoAnswer_AdaptiveCard. Tests QnAMakerDialog with Adaptive Cards.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="Task"/>.</returns>
|
||||
[Fact]
|
||||
public async Task QnAMakerAction_MultiTurnDialogBase_WithNoAnswer_AdaptiveCard()
|
||||
{
|
||||
var rootDialog = QnAMakerAction_MultiTurnDialogBase_AdaptiveCard();
|
||||
|
||||
var response = JsonConvert.DeserializeObject<QueryResults>(File.ReadAllText(GetFilePath("QnaMaker_ReturnAnswer_withPrompts.json")));
|
||||
var promptsActivity = QnACardBuilder.GetQnAPromptsCard(response.Answers[0]);
|
||||
var qnAMakerCardEqualityComparer = new QnAMakerCardEqualityComparer();
|
||||
|
||||
await CreateFlow(rootDialog, nameof(QnAMakerAction_MultiTurnDialogBase_WithNoAnswer_AdaptiveCard))
|
||||
.Send("I have issues related to KB")
|
||||
.AssertReply(promptsActivity, equalityComparer: qnAMakerCardEqualityComparer)
|
||||
.Send("None of the above.")
|
||||
.AssertReply("Thanks for the feedback.")
|
||||
.StartTestAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The QnaMaker_TraceActivity.
|
||||
/// </summary>
|
||||
|
@ -1972,6 +2111,72 @@ namespace Microsoft.Bot.Builder.AI.Tests
|
|||
return rootDialog;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The CreateQnAMakerActionDialog_AdaptiveCard. Tests Adaptive Cards in QnAMakerDialog.
|
||||
/// </summary>
|
||||
/// <param name="mockHttp">The mockHttp<see cref="MockHttpMessageHandler"/>.</param>
|
||||
/// <returns>The <see cref="AdaptiveDialog"/>.</returns>
|
||||
private AdaptiveDialog CreateQnAMakerActionDialog_AdaptiveCard(MockHttpMessageHandler mockHttp)
|
||||
{
|
||||
var client = new HttpClient(mockHttp);
|
||||
|
||||
var noAnswerActivity = new ActivityTemplate("No match found, please ask another question.");
|
||||
const string host = "https://dummy-hostname.azurewebsites.net/qnamaker";
|
||||
const string knowledgeBaseId = "dummy-id";
|
||||
const string endpointKey = "dummy-key";
|
||||
const string activeLearningCardTitle = "QnAMaker Active Learning";
|
||||
|
||||
var outerDialog = new AdaptiveDialog("outer")
|
||||
{
|
||||
AutoEndDialog = false,
|
||||
Triggers = new List<OnCondition>
|
||||
{
|
||||
new OnBeginDialog
|
||||
{
|
||||
Actions = new List<Dialog>
|
||||
{
|
||||
new QnAMakerDialog
|
||||
{
|
||||
KnowledgeBaseId = knowledgeBaseId,
|
||||
HostName = host,
|
||||
EndpointKey = endpointKey,
|
||||
HttpClient = client,
|
||||
NoAnswer = noAnswerActivity,
|
||||
ActiveLearningCardTitle = activeLearningCardTitle,
|
||||
CardNoMatchText = "None of the above.",
|
||||
UseTeamsAdaptiveCard = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var rootDialog = new AdaptiveDialog("root")
|
||||
{
|
||||
Triggers = new List<OnCondition>
|
||||
{
|
||||
new OnBeginDialog
|
||||
{
|
||||
Actions = new List<Dialog>
|
||||
{
|
||||
new BeginDialog(outerDialog.Id)
|
||||
}
|
||||
},
|
||||
new OnDialogEvent
|
||||
{
|
||||
Event = "UnhandledUnknownIntent",
|
||||
Actions = new List<Dialog>
|
||||
{
|
||||
new EditArray(),
|
||||
new SendActivity("magenta")
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
rootDialog.Dialogs.Add(outerDialog);
|
||||
return rootDialog;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The GetV2LegacyRequestUrl.
|
||||
/// </summary>
|
||||
|
|
Загрузка…
Ссылка в новой задаче