public string Help(T state, FormState form, string commandHelp) { var recognizer = _prompt.Recognizer; var prompt = new Prompter <T>(Field.Template(TemplateUsage.HelpNavigation), _form, recognizer); return("* " + prompt.Prompt(state, _name, "* " + recognizer.Help(state, null), commandHelp)); }
public FormPrompt NotUnderstood(IDialogContext context, T state, FormState form, IMessageActivity input) { var template = _field.Template(TemplateUsage.NotUnderstood); var prompter = new Prompter <T>(template, _field.Form, null); return(prompter.Prompt(state, _field, MessageActivityHelper.GetSanitizedTextInput(input))); }
public FormPrompt NotUnderstood(IDialogContext context, T state, FormState form, string input) { var template = _field.Template(TemplateUsage.NotUnderstood); var prompter = new Prompter <T>(template, _field.Form, null); return(prompter.Prompt(state, _field, input)); }
public string Help(T state, FormState form, string commandHelp) { var template = _field.Template(TemplateUsage.HelpConfirm); var prompt = new Prompter <T>(template, _field.Form, _field.Prompt.Recognizer); return("* " + prompt.Prompt(state, _field.Name, "* " + prompt.Recognizer.Help(state, null), commandHelp)); }
public FormPrompt Start(IDialogContext context, T state, FormState form) { form.SetPhase(StepPhase.Completed); var prompt = new Prompter <T>(_promptDefinition, _form, null); return(prompt.Prompt(state, null)); }
private IPrompt <T> NextClarifyPrompt(T state, FieldStepState stepState, IRecognize <T> recognizer, out Ambiguous clarify) { IPrompt <T> prompter = null; clarify = null; foreach (var clarification in stepState.Clarifications) { if (clarification.Values.Length > 1) { clarify = clarification; break; } } if (clarify != null) { var field = new Field <T>("__clarify__", FieldRole.Value); field.Form = _field.Form; var template = _field.Template(TemplateUsage.Clarify); var helpTemplate = _field.Template(template.AllowNumbers ? TemplateUsage.EnumOneNumberHelp : TemplateUsage.EnumManyNumberHelp); field.SetPrompt(new PromptAttribute(template)); field.ReplaceTemplate(_field.Template(TemplateUsage.Clarify)); field.ReplaceTemplate(helpTemplate); foreach (var value in clarify.Values) { field.AddDescription(value, recognizer.ValueDescription(value)); field.AddTerms(value, recognizer.ValidInputs(value).ToArray()); } var choiceRecognizer = new RecognizeEnumeration <T>(field); prompter = new Prompter <T>(template, _field.Form, choiceRecognizer); } return(prompter); }
public override string Help(T state, object defaultValue) { var prompt = new Prompter <T>(_field.Template(TemplateUsage.DateTimeHelp), _field.Form, null); var args = HelpArgs(state, defaultValue); return(prompt.Prompt(state, _field, args.ToArray()).Prompt); }
public virtual IPrompt <T> Prompt() { if (_prompt == null) { _prompt = new Prompter <T>(_promptDefinition, _form, _recognizer); } return(_prompt); }
public override IPrompt <T> Prompt() { if (_prompter == null) { _prompter = new Prompter <T>(_promptDefinition, _form, new RecognizeBool <T>(this)); } return(_prompter); }
public FormPrompt Help(T state, FormState form, string commandHelp) { var template = _field.Template(TemplateUsage.HelpConfirm); var prompt = new Prompter <T>(template, _field.Form, _field.Prompt.Recognizer); var help = prompt.Prompt(state, _field, "* " + prompt.Recognizer.Help(state, null), commandHelp); return(new FormPrompt { Prompt = "* " + help.Prompt, Buttons = help.Buttons }); }
public FormPrompt Help(T state, FormState form, string commandHelp) { var recognizer = _field.Prompt.Recognizer; var prompt = new Prompter <T>(_field.Template(TemplateUsage.HelpNavigation), _field.Form, recognizer, _fields); var help = prompt.Prompt(state, _field, "* " + recognizer.Help(state, null), commandHelp); return(new FormPrompt { Prompt = "* " + help.Prompt, Buttons = help.Buttons }); }
public override string Help(T state, object defaultValue) { var prompt = new Prompter <T>(_field.Template(TemplateUsage.DoubleHelp), _field.Form, null); var args = HelpArgs(state, defaultValue); if (_showLimits) { args.Add(_min); args.Add(_max); } return(prompt.Prompt(state, _field, args.ToArray()).Prompt); }
public override string Help(T state, object defaultValue) { var prompt = new Prompter <T>( _field.Template(this.multipleAttachments ? TemplateUsage.AttachmentCollectionHelp : TemplateUsage.AttachmentFieldHelp), _field.Form, null); // create instance just to call virtual method var awaitableAttachment = Activator.CreateInstance(this.GetAttachmentTypeFromField(), default(Attachment)) as AwaitableAttachment; return(prompt.Prompt(state, _field, awaitableAttachment.ProvideHelp(_field)).Prompt); }
protected void DefineRecognizer() { if (_recognizer == null) { if (_type == null || _type.IsEnum) { _recognizer = new RecognizeEnumeration <T>(this); } else if (_type == typeof(bool)) { _recognizer = new RecognizeBool <T>(this); } else if (_type == typeof(string)) { _recognizer = new RecognizeString <T>(this); } else if (_type.IsIntegral()) { _recognizer = new RecognizeNumber <T>(this); } else if (_type.IsDouble()) { _recognizer = new RecognizeDouble <T>(this); } else if (_type == typeof(DateTime)) { _recognizer = new RecognizeDateTime <T>(this); } else if (_type.IsAttachmentType() || _type.IsAttachmentCollection()) { _recognizer = new RecognizeAttachment <T>(this, _type.IsAttachmentCollection()); } else if (_type.IsIEnumerable()) { var elt = _type.GetGenericElementType(); if (elt.IsEnum) { _recognizer = new RecognizeEnumeration <T>(this); } } _buildPrompts = true; } if (_buildPrompts) { var template = Template(TemplateUsage.Help); _help = new Prompter <T>(template, _form, _recognizer); var prompt = _promptDefinition; _prompt = new Prompter <T>(_promptDefinition, _form, _recognizer); _buildPrompts = false; } }
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); }
protected void DefineRecognizer() { if (_recognizer == null) { if (_type == null || _type.IsEnum) { _recognizer = new RecognizeEnumeration <T>(this); } else if (_type == typeof(bool)) { _recognizer = new RecognizeBool <T>(this); } else if (_type == typeof(string)) { _recognizer = new RecognizeString <T>(this); } else if (_type.IsIntegral()) { _recognizer = new RecognizeNumber <T>(this, Thread.CurrentThread.CurrentUICulture); } else if (_type.IsDouble()) { _recognizer = new RecognizeDouble <T>(this, Thread.CurrentThread.CurrentUICulture); } else if (_type == typeof(DateTime)) { _recognizer = new RecognizeDateTime <T>(this, Thread.CurrentThread.CurrentUICulture); } else if (_type.IsIEnumerable()) { var elt = _type.GetGenericElementType(); if (elt.IsEnum) { _recognizer = new RecognizeEnumeration <T>(this); } } var template = Template(TemplateUsage.Help); _help = new Prompter <T>(template, _form, _recognizer); var prompt = _promptDefinition; _prompt = new Prompter <T>(_promptDefinition, _form, _recognizer); } }
public NavigationField(string name, string startField, IForm <T> form, T state, FormState formState, Fields <T> fields) : base(name, FieldRole.Value) { Form = form; var field = form.Fields.Field(startField); SetFieldDescription(_form.Configuration.Navigation); SetOptional(); foreach (var value in formState.Next.Names) { var svalue = (string)value; var sfield = form.Fields.Field(svalue); var fieldPrompt = sfield.Template(TemplateUsage.NavigationFormat); var prompter = new Prompter <T>(fieldPrompt, form, sfield.Prompt.Recognizer); AddDescription(value, prompter.Prompt(state, sfield).Prompt, null, sfield.FieldDescription.Message ?? sfield.FieldDescription.Description); AddTerms(value, form.Fields.Field(svalue).FieldTerms.ToArray()); } var template = field.Template(TemplateUsage.Navigation); SetPrompt(new PromptAttribute(template)); SetRecognizer(new RecognizeEnumeration <T>(this)); _prompt = new Prompter <T>(template, form, _recognizer, fields); }
public NavigationStep(string name, IForm <T> form, T state, FormState formState) { _name = name; _form = form; _fields = form.Fields; var field = _fields.Field(_name); var template = field.Template(TemplateUsage.Navigation); var recField = new Field <T>("__navigate__", FieldRole.Value) .SetPrompt(new PromptAttribute(template)); recField.Form = form; var fieldPrompt = field.Template(TemplateUsage.NavigationFormat); foreach (var value in formState.Next.Names) { var prompter = new Prompter <T>(fieldPrompt, form, _fields.Field(value as string).Prompt.Recognizer); recField .AddDescription(value, prompter.Prompt(state, value as string)) .AddTerms(value, _fields.Field(value as string).FieldTerms.ToArray()); } var recognizer = new RecognizeEnumeration <T>(recField); _prompt = new Prompter <T>(template, form, recognizer); }
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)); }
private string ExpandTemplate(string template, string currentChoice, string noValue, T state, IField <T> field, object[] args, ref IList <DescribeAttribute> buttons) { bool foundUnspecified = false; int last = 0; int numeric; var response = new StringBuilder(); foreach (Match match in _args.Matches(template)) { var expr = match.Groups[1].Value.Trim(); var substitute = ""; if (expr.StartsWith("&")) { var name = expr.Substring(1); if (name == "" && field != null) { name = field.Name; } var pathField = _fields.Field(name); substitute = Language.Normalize(pathField == null ? field.Name : pathField.FieldDescription.Description, _annotation.FieldCase); } else if (expr == "||") { var builder = new StringBuilder(); var values = _recognizer.ValueDescriptions(); var useButtons = !field.AllowsMultiple && (_annotation.ChoiceStyle == ChoiceStyleOptions.Auto || _annotation.ChoiceStyle == ChoiceStyleOptions.Buttons || _annotation.ChoiceStyle == ChoiceStyleOptions.Carousel); if (values.Any() && _annotation.AllowDefault != BoolDefault.False && field.Optional) { values = values.Concat(new DescribeAttribute[] { new DescribeAttribute(Language.Normalize(noValue, _annotation.ChoiceCase)) }); } string current = null; if (_annotation.AllowDefault != BoolDefault.False) { if (!field.Optional) { if (!field.IsUnknown(state)) { current = ExpandTemplate(currentChoice, null, noValue, state, field, args, ref buttons); } } else { current = ExpandTemplate(currentChoice, null, noValue, state, field, args, ref buttons); } } if (values.Any()) { if (useButtons) { foreach (var value in values) { buttons.Add(value); } } else { // Buttons do not support multiple selection so we fall back to text if (((_annotation.ChoiceStyle == ChoiceStyleOptions.Auto || _annotation.ChoiceStyle == ChoiceStyleOptions.AutoText) && values.Count() < 4) || (_annotation.ChoiceStyle == ChoiceStyleOptions.Inline)) { // Inline choices if (_annotation.ChoiceParens == BoolDefault.True) { builder.Append('('); } var choices = new List <string>(); var i = 1; foreach (var value in values) { choices.Add(string.Format(_annotation.ChoiceFormat, i, Language.Normalize(value.Description, _annotation.ChoiceCase))); ++i; } builder.Append(Language.BuildList(choices, _annotation.ChoiceSeparator, _annotation.ChoiceLastSeparator)); if (_annotation.ChoiceParens == BoolDefault.True) { builder.Append(')'); } if (current != null) { builder.Append(" "); builder.Append(current); } } else { // Separate line choices if (current != null) { builder.Append(current); builder.Append(" "); } var i = 1; foreach (var value in values) { builder.Append("\n "); if (!_annotation.AllowNumbers) { builder.Append("* "); } builder.AppendFormat(_annotation.ChoiceFormat, i, Language.Normalize(value.Description, _annotation.ChoiceCase)); ++i; } } } } else if (current != null) { builder.Append(" "); builder.Append(current); } substitute = builder.ToString(); } else if (expr.StartsWith("*")) { // Status display of active results var filled = expr.ToLower().Trim().EndsWith("filled"); var builder = new StringBuilder(); var format = new Prompter <T>(Template(field, TemplateUsage.StatusFormat), _form, null); if (match.Index > 0) { builder.Append("\n"); } foreach (var entry in (from step in _fields where (!filled || !step.IsUnknown(state)) && step.Role == FieldRole.Value && step.Active(state) select step)) { builder.Append("* ").AppendLine(format.Prompt(state, entry).Prompt); } substitute = builder.ToString(); } else if (expr.StartsWith("[") && expr.EndsWith("]")) { // Generate a list from multiple fields var paths = expr.Substring(1, expr.Length - 2).Split(' '); var values = new List <Tuple <IField <T>, object, string> >(); foreach (var spec in paths) { if (!spec.StartsWith("{") || !spec.EndsWith("}")) { throw new ArgumentException("Only {<field>} references are allowed in lists."); } var formatArgs = spec.Substring(1, spec.Length - 2).Trim().Split(':'); var name = formatArgs[0]; if (name == "" && field != null) { name = field.Name; } var format = (formatArgs.Length > 1 ? "0:" + formatArgs[1] : "0"); var eltDesc = _fields.Field(name); if (!eltDesc.IsUnknown(state)) { var value = eltDesc.GetValue(state); if (value.GetType() != typeof(string) && value.GetType().IsIEnumerable()) { var eltValues = (value as System.Collections.IEnumerable); foreach (var elt in eltValues) { values.Add(Tuple.Create(eltDesc, elt, format)); } } else { values.Add(Tuple.Create(eltDesc, eltDesc.GetValue(state), format)); } } } if (values.Count() > 0) { var elements = (from elt in values select Language.Normalize(ValueDescription(elt.Item1, elt.Item2, elt.Item3), _annotation.ValueCase)).ToArray(); substitute = Language.BuildList(elements, _annotation.Separator, _annotation.LastSeparator); } } else if (expr.StartsWith("?")) { // Conditional template var subValue = ExpandTemplate(expr.Substring(1), currentChoice, null, state, field, args, ref buttons); if (subValue == null) { substitute = ""; } else { substitute = subValue; } } else if (TryParseFormat(expr, out numeric)) { // Process ad hoc arg if (numeric < args.Length && args[numeric] != null) { substitute = string.Format("{" + expr + "}", args); } else { foundUnspecified = true; break; } } else { var formatArgs = expr.Split(':'); var name = formatArgs[0]; if (name == "" && field != null) { name = field.Name; } var pathDesc = _fields.Field(name); if (pathDesc.IsUnknown(state)) { if (noValue == null) { foundUnspecified = true; break; } substitute = noValue; } else { var value = pathDesc.GetValue(state); if (value.GetType() != typeof(string) && value.GetType().IsIEnumerable()) { var values = (value as System.Collections.IEnumerable); substitute = Language.BuildList(from elt in values.Cast <object>() select Language.Normalize(ValueDescription(pathDesc, elt, "0"), _annotation.ValueCase), _annotation.Separator, _annotation.LastSeparator); } else { var format = (formatArgs.Length > 1 ? "0:" + formatArgs[1] : "0"); substitute = ValueDescription(pathDesc, value, format); } } } response.Append(template.Substring(last, match.Index - last)).Append(substitute); last = match.Index + match.Length; } return(foundUnspecified ? null : response.Append(template.Substring(last, template.Length - last)).ToString()); }
public MessageStep(PromptAttribute prompt, ConditionalDelegate <T> condition, IForm <T> form) { _name = "message" + form.Steps.Count.ToString(); _prompt = new Prompter <T>(prompt, form, null); _condition = (condition == null ? (state) => true : condition); }