internal static IList <Attachment> GenerateHeroCard(this FormPrompt prompt) { var actions = new List <CardAction>(); foreach (var button in prompt.Buttons) { actions.Add(new CardAction(ActionTypes.ImBack, button.Description, button.Image, button.Message ?? button.Description)); } var attachments = new List <Attachment>(); if (actions.Count > 0) { var description = prompt.Description; attachments.Add(new HeroCard(text: prompt.Prompt, title: description.Title, subtitle: description.SubTitle, buttons: actions, images: prompt.Description?.Image == null ? null : new List <CardImage>() { new CardImage() { Url = description.Image } }) .ToAttachment()); } return(attachments); }
internal static IList <Attachment> GenerateHeroCards(this FormPrompt prompt) { var attachments = new List <Attachment>(); var description = prompt.Description; foreach (var button in prompt.Buttons) { string image = button.Image ?? description.Image; attachments.Add(new HeroCard( title: button.Title ?? description.Title, subtitle: button.SubTitle ?? description.SubTitle, text: prompt.Prompt, images: (image == null ? null : (new List <CardImage>() { new CardImage() { Url = image } })), buttons: new List <CardAction>() { new CardAction(ActionTypes.ImBack, button.Description, null, button.Message ?? button.Description) }) .ToAttachment()); } return(attachments); }
internal static IList <Attachment> GenerateHeroCard(this FormPrompt prompt) { var actions = new List <CardAction>(); foreach (var button in prompt.Buttons) { actions.Add(new CardAction(ActionTypes.ImBack, button.Description, button.Image, button.Message ?? button.Description)); } var attachments = new List <Attachment>(); if (actions.Count > 0) { var description = prompt.Description; // Facebook requires a title https://github.com/Microsoft/BotBuilder/issues/1678 attachments.Add(new HeroCard(text: prompt.Prompt, title: description.Title ?? string.Empty, subtitle: description.SubTitle, buttons: actions, images: prompt.Description?.Image == null ? null : new List <CardImage>() { new CardImage() { Url = description.Image } }) .ToAttachment()); } return(attachments); }
internal StepResult(bool success, NextStep next, FormPrompt feedback, FormPrompt prompt) { this.Success = success; this.Next = next; this.Feedback = feedback; this.Prompt = prompt; }
/// <summary> /// Deep clone the FormPrompt. /// </summary> /// <returns> A deep cloned instance of FormPrompt.</returns> public object Clone() { var newPrompt = new FormPrompt(); newPrompt.Prompt = this.Prompt; newPrompt.Buttons = this.Buttons.Clone(); return(newPrompt); }
internal StepResult(bool success, NextStep next, FormPrompt feedback, FormPrompt prompt, string promptOverride = null) { this.Success = success; this.Next = next; this.Feedback = feedback; this.Prompt = prompt; this.PromptOverride = promptOverride; }
/// <summary> /// Deep clone the FormPrompt. /// </summary> /// <returns> A deep cloned instance of FormPrompt.</returns> public object Clone() { var newPrompt = new FormPrompt(); newPrompt.Prompt = this.Prompt; newPrompt.Description = this.Description; newPrompt.Buttons = new List <DescribeAttribute>(this.Buttons); newPrompt.Style = this.Style; return(newPrompt); }
private FormPrompt ClarifyPrompt(FieldStepState stepState, IRecognize <T> recognizer, T state) { var clarify = NeedsClarification(stepState); FormPrompt prompt = null; if (clarify != null) { var field = ClarifyField(clarify, recognizer); var prompter = new Prompter <T>(field.Template(TemplateUsage.Clarify), field.Form, new RecognizeEnumeration <T>(field)); prompt = prompter.Prompt(state, field, clarify.Response); } return(prompt); }
public FormPrompt NotUnderstood(IDialogContext context, T state, FormState form, string input) { FormPrompt feedback = null; var iprompt = _field.Prompt; var fieldState = (FieldStepState)form.StepState; if (fieldState.State == FieldStepStates.SentPrompt) { feedback = Template(TemplateUsage.NotUnderstood).Prompt(state, _field, input); } else if (fieldState.State == FieldStepStates.SentClarify) { feedback = Template(TemplateUsage.NotUnderstood).Prompt(state, _field, input); } return(feedback); }
public FormPrompt NotUnderstood(IDialogContext context, T state, FormState form, IMessageActivity input) { var inputText = MessageActivityHelper.GetSanitizedTextInput(input); FormPrompt feedback = null; var iprompt = _field.Prompt; var fieldState = (FieldStepState)form.StepState; if (fieldState.State == FieldStepStates.SentPrompt) { feedback = Template(TemplateUsage.NotUnderstood).Prompt(state, _field, inputText); } else if (fieldState.State == FieldStepStates.SentClarify) { feedback = Template(TemplateUsage.NotUnderstood, ClarifyRecognizer(fieldState, _field.Prompt.Recognizer)).Prompt(state, _field, inputText); } return(feedback); }
public async Task <StepResult> ProcessAsync(IDialogContext context, T state, FormState form, string input, IEnumerable <TermMatch> matches) { ValidateResult feedback = new ValidateResult(); feedback.IsValid = true; feedback.Feedback = null; feedback.FeedbackCard = null; feedback.Choices = null; FormPrompt prompt = null; FormPrompt feedbackPrompt = null; var iprompt = _field.Prompt; var fieldState = (FieldStepState)form.StepState; object response = null; if (fieldState.State == FieldStepStates.SentPrompt) { // Response to prompt var firstMatch = matches.FirstOrDefault(); if (matches.Count() == 1) { response = firstMatch.Value; if (_field.AllowsMultiple && response != null && (response.GetType() == typeof(string) || !response.GetType().IsIEnumerable())) { response = new List <object>() { response }; } feedback = await SetValueAsync(state, response, form); if (!feedback.IsValid && feedback.Choices != null) { var choices = new Ambiguous(input.Substring(firstMatch.Start, firstMatch.Length), feedback.Choices); fieldState.State = FieldStepStates.SentClarify; fieldState.Settled = new List <object>(); fieldState.Clarifications = new List <Ambiguous>() { choices }; response = SetValue(state, null); prompt = ClarifyPrompt((FieldStepState)form.StepState, iprompt.Recognizer, state); } } else if (matches.Count() > 1) { // Check multiple matches for ambiguity var groups = MatchAnalyzer.GroupedMatches(matches); // 1) Could be multiple match groups like for ingredients. // 2) Could be overlapping matches like "onion". // 3) Could be multiple matches where only one is expected. if (!_field.AllowsMultiple) { // Create a single group of all possibilities if only want one value var mergedGroup = groups.SelectMany((group) => group).ToList(); groups = new List <List <TermMatch> >() { mergedGroup }; } var ambiguous = new List <Ambiguous>(); var settled = new List <object>(); foreach (var choices in groups) { if (choices.Count > 1) { var unclearResponses = string.Join(" ", (from choice in choices select input.Substring(choice.Start, choice.Length)).Distinct()); var values = from match in choices select match.Value; ambiguous.Add(new Ambiguous(unclearResponses, values)); } else { var matchValue = choices.First().Value; if (matchValue != null && matchValue.GetType() != typeof(string) && matchValue.GetType().IsIEnumerable()) { foreach (var value in (System.Collections.IEnumerable)matchValue) { settled.Add(value); } } else { settled.Add(choices.First().Value); } } } if (settled.Count > 1) { // Remove no preference if present settled.Remove(null); } if (ambiguous.Count > 0) { // Need 1 or more clarifications fieldState.State = FieldStepStates.SentClarify; fieldState.Settled = settled; fieldState.Clarifications = ambiguous; response = SetValue(state, null); prompt = ClarifyPrompt((FieldStepState)form.StepState, iprompt.Recognizer, state); } else { if (_field.AllowsMultiple) { response = settled; feedback = await SetValueAsync(state, response, form); } else { Debug.Assert(settled.Count == 1); response = settled.First(); feedback = await SetValueAsync(state, response, form); } } } var unmatched = MatchAnalyzer.Unmatched(input, matches); var unmatchedWords = string.Join(" ", unmatched); var nonNoise = Language.NonNoiseWords(Language.WordBreak(unmatchedWords)).ToArray(); fieldState.Unmatched = null; if (_field.Prompt.Annotation.Feedback == FeedbackOptions.Always) { fieldState.Unmatched = string.Join(" ", nonNoise); } else if (_field.Prompt.Annotation.Feedback == FeedbackOptions.Auto && nonNoise.Any() && unmatched.Any()) { fieldState.Unmatched = string.Join(" ", nonNoise); } } else if (fieldState.State == FieldStepStates.SentClarify) { if (matches.Count() == 1) { // Clarified ambiguity var clarify = NeedsClarification(fieldState); fieldState.Settled.Add(matches.First().Value); fieldState.Clarifications.Remove(clarify); if (prompt == null) { // No clarification left, so set the field if (_field.AllowsMultiple) { response = fieldState.Settled; feedback = await SetValueAsync(state, response, form); } else { Debug.Assert(fieldState.Settled.Count == 1); response = fieldState.Settled.First(); feedback = await SetValueAsync(state, response, form); } form.SetPhase(StepPhase.Completed); } } } if (form.Phase() == StepPhase.Completed) { form.StepState = null; if (fieldState.Unmatched != null) { if (feedback.FeedbackCard != null) { feedbackPrompt = feedback.FeedbackCard; } else if (feedback.Feedback != null) { feedbackPrompt = new FormPrompt { Prompt = feedback.Feedback }; } else { if (fieldState.Unmatched != "") { feedbackPrompt = new Prompter <T>(_field.Template(TemplateUsage.Feedback), _field.Form, null).Prompt(state, _field, fieldState.Unmatched); } else { feedbackPrompt = new Prompter <T>(_field.Template(TemplateUsage.Feedback), _field.Form, null).Prompt(state, _field); } } } } var next = _field.Next(response, state); return(new StepResult(feedback.IsValid, next, feedbackPrompt ?? (feedback.FeedbackCard ?? new FormPrompt { Prompt = feedback.Feedback }), prompt)); }
/// <summary> /// Given a prompt definition generate messages to send back. /// </summary> /// <param name="prompt">Prompt definition.</param> /// <param name="preamble">Simple text message with all except last line of prompt to allow markdown in prompts.</param> /// <param name="promptMessage">Message with prompt definition including cards.</param> /// <returns>True if preamble should be sent.</returns> public static bool GenerateMessages(this FormPrompt prompt, IMessageActivity preamble, IMessageActivity promptMessage) { var promptCopy = (FormPrompt)prompt.Clone(); bool hasPreamble = false; if (promptCopy.Buttons?.Count > 0 || promptCopy.Description?.Image != null) { // If we are generating cards we do not support markdown so create a separate message // for all lines except the last one. var lines = promptCopy.Prompt.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); if (lines.Length > 1) { var builder = new StringBuilder(); for (var i = 0; i < lines.Length - 1; ++i) { if (i > 0) { builder.AppendLine(); } builder.Append(lines[i]); } preamble.Text = builder.ToString(); promptCopy.Prompt = lines.Last(); hasPreamble = true; } if (promptCopy.Buttons?.Count > 0) { var style = promptCopy.Style; if (style == ChoiceStyleOptions.Auto) { foreach (var button in promptCopy.Buttons) { // Images require carousel if (button.Image != null) { style = ChoiceStyleOptions.Carousel; break; } } } if (style == ChoiceStyleOptions.Carousel) { promptMessage.AttachmentLayout = AttachmentLayoutTypes.Carousel; promptMessage.Attachments = promptCopy.GenerateHeroCards(); } else { promptMessage.AttachmentLayout = AttachmentLayoutTypes.List; promptMessage.Attachments = promptCopy.GenerateHeroCard(); } } else if (promptCopy.Description?.Image != null) { promptMessage.AttachmentLayout = AttachmentLayoutTypes.List; var card = new HeroCard() { Title = promptCopy.Prompt, Images = new List <CardImage> { new CardImage(promptCopy.Description.Image) } }; promptMessage.Attachments = new List <Attachment> { card.ToAttachment() }; } } else { promptMessage.Text = promptCopy.Prompt; } return(hasPreamble); }
internal StepResult(NextStep next, FormPrompt feedback, FormPrompt prompt) { this.Next = next; this.Feedback = feedback; this.Prompt = prompt; }