diff --git a/libraries/Microsoft.Bot.Builder.AI.LUIS/LuisRecognizer.cs b/libraries/Microsoft.Bot.Builder.AI.LUIS/LuisRecognizer.cs index d05f8bfa97..a3d0333784 100644 --- a/libraries/Microsoft.Bot.Builder.AI.LUIS/LuisRecognizer.cs +++ b/libraries/Microsoft.Bot.Builder.AI.LUIS/LuisRecognizer.cs @@ -48,7 +48,6 @@ public class LuisRecognizer : Recognizer, ITelemetryRecognizer /// /// Initializes a new instance of the class. /// - /// The LUIS application to use to recognize text. /// The LUIS recognizer version options. /// (Optional) Custom handler for LUIS API calls to allow mocking. public LuisRecognizer(LuisRecognizerOptions recognizerOptions, HttpClientHandler clientHandler = null) diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ActionScope.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ActionScope.cs index 998ac3e2d7..8cea3723aa 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ActionScope.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ActionScope.cs @@ -49,8 +49,10 @@ public override async Task ResumeDialogAsync(DialogContext dc, return await OnActionScopeResultAsync(dc, actionScopeResult, cancellationToken).ConfigureAwait(false); } + var dcState = dc.GetState(); + // When we are resumed, we increment our offset into the actions and being the next action - var nextOffset = dc.GetState().GetIntValue(OFFSETKEY, 0) + 1; + var nextOffset = dcState.GetIntValue(OFFSETKEY, 0) + 1; if (nextOffset < this.Actions.Count) { return await this.BeginActionAsync(dc, nextOffset, cancellationToken: cancellationToken).ConfigureAwait(false); @@ -135,7 +137,9 @@ protected virtual async Task OnEndOfActionsAsync(DialogContext protected virtual async Task BeginActionAsync(DialogContext dc, int offset, CancellationToken cancellationToken = default) { // get the action for the offset - dc.GetState().SetValue(OFFSETKEY, offset); + var dcState = dc.GetState(); + + dcState.SetValue(OFFSETKEY, offset); var actionId = this.Actions[offset].Id; // begin Action dialog diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BaseInvokeDialog.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BaseInvokeDialog.cs index 42566580f5..7fa94f4174 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BaseInvokeDialog.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BaseInvokeDialog.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using Microsoft.Bot.Builder.Dialogs.Declarative; using Microsoft.Bot.Expressions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -16,12 +17,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions public abstract class BaseInvokeDialog : Dialog, IDialogDependencies { // Expression for dialogId to call (allowing dynamic expression) - private string dialogIdToCall; - - public BaseInvokeDialog(string dialogIdToCall = null, IDictionary bindingOptions = null) + public BaseInvokeDialog(string dialogIdToCall = null, object bindingOptions = null) : base() { - this.dialogIdToCall = dialogIdToCall; + if (dialogIdToCall != null) + { + this.Dialog = dialogIdToCall; + } if (bindingOptions != null) { @@ -36,7 +38,7 @@ public BaseInvokeDialog(string dialogIdToCall = null, IDictionary [JsonProperty("options")] - public object Options { get; set; } = new JObject(); + public ObjectExpression Options { get; set; } = new ObjectExpression(); /// /// Gets or sets the dialog to call. @@ -45,7 +47,7 @@ public BaseInvokeDialog(string dialogIdToCall = null, IDictionary [JsonProperty("dialog")] - public Dialog Dialog { get; set; } + public DialogExpression Dialog { get; set; } /// /// Gets or sets a value indicating whether to have the new dialog should process the activity. @@ -53,13 +55,13 @@ public BaseInvokeDialog(string dialogIdToCall = null, IDictionaryThe default for this will be true, which means the new dialog should not look the activity. You can set this to false to dispatch the activity to the new dialog. [DefaultValue(true)] [JsonProperty("activityProcessed")] - public bool ActivityProcessed { get; set; } = true; + public BoolExpression ActivityProcessed { get; set; } = true; public virtual IEnumerable GetDependencies() { - if (Dialog != null) + if (Dialog?.Value != null) { - yield return Dialog; + yield return Dialog.Value; } yield break; @@ -67,30 +69,36 @@ public virtual IEnumerable GetDependencies() protected override string OnComputeId() { - return $"{this.GetType().Name}[{Dialog?.Id ?? this.dialogIdToCall}]"; + return $"{this.GetType().Name}[{Dialog?.ToString()}]"; } protected Dialog ResolveDialog(DialogContext dc) { - if (this.Dialog != null) + if (this.Dialog?.Value != null) { - return this.Dialog; + return this.Dialog.Value; } - var dialogId = this.dialogIdToCall ?? throw new Exception($"{this.GetType().Name} requires a dialog to be called."); - return dc.FindDialog(dialogId) ?? throw new Exception($"{dialogId} not found."); + var dcState = dc.GetState(); + + // NOTE: we call TryEvaluate instead of TryGetValue because we want the result of the expression as a string so we can + // look up the string using external FindDialog(). + var (dialogId, _) = this.Dialog.Expression.TryEvaluate(dcState); + return dc.FindDialog(dialogId ?? throw new Exception($"{this.Dialog.ToString()} not found.")); } protected object BindOptions(DialogContext dc, object options) { + var dcState = dc.GetState(); + // binding options are static definition of options with overlay of passed in options); - var bindingOptions = (JObject)ObjectPath.Merge(Options, options ?? new JObject()); + var bindingOptions = (JObject)ObjectPath.Merge(this.Options.GetValue(dcState), options ?? new JObject()); var boundOptions = new JObject(); foreach (var binding in bindingOptions) { // evalute the value - var (result, error) = new ExpressionEngine().Parse(binding.Value.ToString()).TryEvaluate(dc.GetState()); + var (value, error) = new ValueExpression(binding.Value).TryGetValue(dcState); if (error != null) { @@ -98,7 +106,7 @@ protected object BindOptions(DialogContext dc, object options) } // and store in options as the result - boundOptions[binding.Key] = JToken.FromObject(result); + ObjectPath.SetPathValue(boundOptions, binding.Key, value); } return boundOptions; diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BeginDialog.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BeginDialog.cs index 93cda41d56..26408588eb 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BeginDialog.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BeginDialog.cs @@ -19,10 +19,8 @@ public class BeginDialog : BaseInvokeDialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.BeginDialog"; - private Expression disabled; - [JsonConstructor] - public BeginDialog(string dialogIdToCall = null, IDictionary options = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) + public BeginDialog(string dialogIdToCall = null, object options = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base(dialogIdToCall, options) { this.RegisterSourceLocation(callerPath, callerLine); @@ -38,11 +36,7 @@ public BeginDialog(string dialogIdToCall = null, IDictionary opt /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets the property path to store the dialog result in. @@ -51,7 +45,7 @@ public string Disabled /// The property path to store the dialog result in. /// [JsonProperty("resultProperty")] - public string ResultProperty { get; set; } + public StringExpression ResultProperty { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -59,8 +53,10 @@ public string Disabled { throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } + + var dcState = dc.GetState(); - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -71,7 +67,7 @@ public string Disabled var boundOptions = BindOptions(dc, options); // set the activity processed state (default is true) - dc.GetState().SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed); + dcState.SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed); // start dialog with bound options passed in as the options return await dc.BeginDialogAsync(dialog.Id, options: boundOptions, cancellationToken: cancellationToken).ConfigureAwait(false); @@ -79,9 +75,11 @@ public string Disabled public override async Task ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken)) { + var dcState = dc.GetState(); + if (this.ResultProperty != null) { - dc.GetState().SetValue(this.ResultProperty, result); + dcState.SetValue(this.ResultProperty.GetValue(dcState), result); } // By default just end the current dialog and return result to parent. diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BreakLoop.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BreakLoop.cs index 046f022fe9..311050f250 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BreakLoop.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/BreakLoop.cs @@ -18,8 +18,6 @@ public class BreakLoop : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.BreakLoop"; - private Expression disabled; - public BreakLoop([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { this.RegisterSourceLocation(callerPath, callerLine); @@ -35,11 +33,7 @@ public BreakLoop([CallerFilePath] string callerPath = "", [CallerLineNumber] int /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -47,8 +41,10 @@ public string Disabled { throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } + + var dcState = dc.GetState(); - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/CancelAllDialogs.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/CancelAllDialogs.cs index a056f43f8d..83c77c14f5 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/CancelAllDialogs.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/CancelAllDialogs.cs @@ -18,8 +18,6 @@ public class CancelAllDialogs : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.CancelAllDialogs"; - private Expression disabled; - [JsonConstructor] public CancelAllDialogs([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() @@ -37,11 +35,7 @@ public CancelAllDialogs([CallerFilePath] string callerPath = "", [CallerLineNumb /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets event name. @@ -50,7 +44,7 @@ public string Disabled /// Event name. /// [JsonProperty("eventName")] - public string EventName { get; set; } + public StringExpression EventName { get; set; } /// /// Gets or sets value expression for EventValue. @@ -59,7 +53,7 @@ public string Disabled /// Value expression for EventValue. /// [JsonProperty("eventValue")] - public string EventValue { get; set; } + public StringExpression EventValue { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -68,24 +62,20 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) - { - return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); - } + var dcState = dc.GetState(); - object eventValue = null; - if (this.EventValue != null) + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { - eventValue = new ExpressionEngine().Parse(this.EventValue).TryEvaluate(dc.GetState()); + return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } if (dc.Parent == null) { - return await dc.CancelAllDialogsAsync(true, EventName, eventValue, cancellationToken).ConfigureAwait(false); + return await dc.CancelAllDialogsAsync(true, EventName.GetValue(dcState), this.EventValue.GetValue(dcState), cancellationToken).ConfigureAwait(false); } else { - var turnResult = await dc.Parent.CancelAllDialogsAsync(true, EventName, eventValue, cancellationToken).ConfigureAwait(false); + var turnResult = await dc.Parent.CancelAllDialogsAsync(true, EventName.GetValue(dcState), this.EventValue.GetValue(dcState), cancellationToken).ConfigureAwait(false); turnResult.ParentEnded = true; return turnResult; } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/CodeAction.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/CodeAction.cs index 311b4b0b2e..4539033cea 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/CodeAction.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/CodeAction.cs @@ -15,7 +15,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions public class CodeAction : Dialog { private readonly CodeActionHandler codeHandler; - private Expression disabled; public CodeAction(CodeActionHandler codeHandler, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() @@ -34,11 +33,7 @@ public CodeAction(CodeActionHandler codeHandler, [CallerFilePath] string callerP /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -47,7 +42,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ContinueLoop.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ContinueLoop.cs index aaf3bed55c..b6378b8955 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ContinueLoop.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ContinueLoop.cs @@ -18,8 +18,6 @@ public class ContinueLoop : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.ContinueLoop"; - private Expression disabled; - public ContinueLoop([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { this.RegisterSourceLocation(callerPath, callerLine); @@ -35,11 +33,7 @@ public ContinueLoop([CallerFilePath] string callerPath = "", [CallerLineNumber] /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -48,7 +42,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DebugBreak.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DebugBreak.cs index 860dc233cb..5307d160f7 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DebugBreak.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DebugBreak.cs @@ -18,8 +18,6 @@ public class DebugBreak : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.DebugBreak"; - private Expression disabled; - public DebugBreak([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { this.RegisterSourceLocation(callerPath, callerLine); @@ -35,11 +33,7 @@ public DebugBreak([CallerFilePath] string callerPath = "", [CallerLineNumber] in /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -48,7 +42,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteActivity.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteActivity.cs index 5714dd17c0..278d21cfed 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteActivity.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteActivity.cs @@ -20,9 +20,6 @@ public class DeleteActivity : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.DeleteActivity"; - private Expression activityId; - private Expression disabled; - [JsonConstructor] public DeleteActivity([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { @@ -39,22 +36,14 @@ public DeleteActivity([CallerFilePath] string callerPath = "", [CallerLineNumber /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets the expression which resolves to the activityId to update. /// /// Expression to activityId. [JsonProperty("activityId")] - public string ActivityId - { - get { return activityId.ToString(); } - set { activityId = new ExpressionEngine().Parse(value); } - } + public StringExpression ActivityId { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -63,12 +52,14 @@ public string ActivityId throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } - var (result, error) = new ExpressionEngine().Parse(this.ActivityId).TryEvaluate(dc.GetState()); + var (result, error) = this.ActivityId.TryGetValue(dcState); if (error != null) { throw new ArgumentException(error); diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteProperties.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteProperties.cs index 52b88aa03a..0bbbbe2dbb 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteProperties.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteProperties.cs @@ -20,8 +20,6 @@ public class DeleteProperties : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.DeleteProperties"; - private Expression disabled; - [JsonConstructor] public DeleteProperties([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() @@ -39,11 +37,7 @@ public DeleteProperties([CallerFilePath] string callerPath = "", [CallerLineNumb /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets properties to remove. @@ -55,7 +49,7 @@ public string Disabled /// Collection of property paths to remove. /// [JsonProperty("properties")] - public List Properties { get; set; } = new List(); + public List Properties { get; set; } = new List(); public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -64,7 +58,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -76,7 +72,7 @@ public string Disabled { foreach (var property in this.Properties) { - dc.GetState().RemoveValue(property); + dcState.RemoveValue(property.GetValue(dcState)); } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteProperty.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteProperty.cs index b17c67f925..f1ebc612f2 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteProperty.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/DeleteProperty.cs @@ -18,8 +18,6 @@ public class DeleteProperty : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.DeleteProperty"; - private Expression disabled; - [JsonConstructor] public DeleteProperty([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() @@ -47,11 +45,7 @@ public DeleteProperty(string property, [CallerFilePath] string callerPath = "", /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets property path to remove. @@ -63,7 +57,7 @@ public string Disabled /// Property path to remove. /// [JsonProperty("property")] - public string Property { get; set; } + public StringExpression Property { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -71,8 +65,10 @@ public string Disabled { throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } + + var dcState = dc.GetState(); - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -80,7 +76,7 @@ public string Disabled // Ensure planning context if (dc is SequenceContext planning) { - dc.GetState().RemoveValue(Property); + dcState.RemoveValue(Property.GetValue(dcState)); return await dc.EndDialogAsync(); } else diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EditActions.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EditActions.cs index 69d4cdea31..d56ff17cd7 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EditActions.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EditActions.cs @@ -20,8 +20,6 @@ public class EditActions : Dialog, IDialogDependencies [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.EditActions"; - private Expression disabled; - /// /// Initializes a new instance of the class. /// @@ -44,11 +42,7 @@ public EditActions([CallerFilePath] string sourceFilePath = "", [CallerLineNumbe /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets the actions to be applied to the active action. @@ -66,7 +60,7 @@ public string Disabled /// The type of change to appy to the active actions. /// [JsonProperty("changeType")] - public ActionChangeType ChangeType { get; set; } + public EnumExpression ChangeType { get; set; } = new EnumExpression(); public virtual IEnumerable GetDependencies() { @@ -75,7 +69,9 @@ public virtual IEnumerable GetDependencies() public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -91,7 +87,7 @@ public virtual IEnumerable GetDependencies() var changes = new ActionChangeList() { - ChangeType = ChangeType, + ChangeType = ChangeType.GetValue(dcState), Actions = planActions.ToList() }; diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EditArray.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EditArray.cs index 5cf3811777..0c35ed5738 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EditArray.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EditArray.cs @@ -22,11 +22,6 @@ public class EditArray : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.EditArray"; - private Expression value; - private Expression itemsProperty; - private Expression resultProperty; - private Expression disabled; - /// /// Initializes a new instance of the class. /// @@ -34,10 +29,10 @@ public class EditArray : Dialog /// array property (optional). /// value to insert. /// output property to put Pop/Take into. - public EditArray(ArrayChangeType changeType, string arrayProperty = null, string value = null, string resultProperty = null) + public EditArray(ArrayChangeType changeType, string arrayProperty = null, object value = null, string resultProperty = null) : base() { - this.ChangeType = changeType; + this.ChangeType = new EnumExpression(changeType); if (!string.IsNullOrEmpty(arrayProperty)) { @@ -49,11 +44,19 @@ public EditArray(ArrayChangeType changeType, string arrayProperty = null, string case ArrayChangeType.Clear: case ArrayChangeType.Pop: case ArrayChangeType.Take: - this.ResultProperty = resultProperty; + if (ResultProperty != null) + { + this.ResultProperty = resultProperty; + } + break; case ArrayChangeType.Push: case ArrayChangeType.Remove: - this.Value = value; + if (value != null) + { + this.Value = new ValueExpression(value); + } + break; } } @@ -101,7 +104,7 @@ public enum ArrayChangeType /// Type of change being applied. /// [JsonProperty("changeType")] - public ArrayChangeType ChangeType { get; set; } + public EnumExpression ChangeType { get; set; } = new EnumExpression(default(ArrayChangeType)); /// /// Gets or sets an optional expression which if is true will disable this action. @@ -113,11 +116,7 @@ public enum ArrayChangeType /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets property path expression to the collection of items. @@ -126,11 +125,7 @@ public string Disabled /// Property path expression to the collection of items. /// [JsonProperty("itemsProperty")] - public string ItemsProperty - { - get { return itemsProperty?.ToString(); } - set { this.itemsProperty = (value != null) ? new ExpressionEngine().Parse(value) : null; } - } + public StringExpression ItemsProperty { get; set; } /// /// Gets or sets the path expression to store the result of the action. @@ -139,11 +134,7 @@ public string ItemsProperty /// The path expression to store the result of the action. /// [JsonProperty("resultProperty")] - public string ResultProperty - { - get { return resultProperty?.ToString(); } - set { this.resultProperty = (value != null) ? new ExpressionEngine().Parse(value) : null; } - } + public StringExpression ResultProperty { get; set; } /// /// Gets or sets the expression of the value to put onto the array. @@ -152,11 +143,7 @@ public string ResultProperty /// The expression of the value to put onto the array. /// [JsonProperty("value")] - public string Value - { - get { return value?.ToString(); } - set { this.value = (value != null) ? new ExpressionEngine().Parse(value) : null; } - } + public ValueExpression Value { get; set; } = new ValueExpression(); public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -165,22 +152,24 @@ public string Value throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState)) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } - if (string.IsNullOrEmpty(ItemsProperty)) + if (ItemsProperty == null) { throw new Exception($"EditArray: \"{ChangeType}\" operation couldn't be performed because the arrayProperty wasn't specified."); } - var array = dc.GetState().GetValue(this.ItemsProperty, () => new JArray()); + var array = dcState.GetValue(this.ItemsProperty.GetValue(dcState), () => new JArray()); object item = null; object result = null; - switch (ChangeType) + switch (ChangeType.GetValue(dcState)) { case ArrayChangeType.Pop: item = array[array.Count - 1]; @@ -189,7 +178,7 @@ public string Value break; case ArrayChangeType.Push: EnsureValue(); - var (itemResult, error) = this.value.TryEvaluate(dc.GetState()); + var (itemResult, error) = this.Value.TryGetValue(dcState); if (error == null && itemResult != null) { array.Add(itemResult); @@ -208,7 +197,7 @@ public string Value break; case ArrayChangeType.Remove: EnsureValue(); - (itemResult, error) = this.value.TryEvaluate(dc.GetState()); + (itemResult, error) = this.Value.TryGetValue(dcState); if (error == null && itemResult != null) { result = false; @@ -230,11 +219,11 @@ public string Value break; } - dc.GetState().SetValue(this.ItemsProperty, array); + dcState.SetValue(this.ItemsProperty.GetValue(dcState), array); if (ResultProperty != null) { - dc.GetState().SetValue(this.ResultProperty, result); + dcState.SetValue(this.ResultProperty.GetValue(dcState), result); } return await dc.EndDialogAsync(result); diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EmitEvent.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EmitEvent.cs index e1fe4a2fc8..48fafeea23 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EmitEvent.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EmitEvent.cs @@ -18,17 +18,23 @@ public class EmitEvent : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.EmitEvent"; - private Expression eventValue; - private Expression disabled; - [JsonConstructor] - public EmitEvent(string eventName = null, string eventValue = null, bool bubble = false, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) + public EmitEvent(string eventName = null, object eventValue = null, bool bubble = false, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() { this.RegisterSourceLocation(callerPath, callerLine); - this.EventName = eventName; - this.EventValue = eventValue; - this.BubbleEvent = bubble; + + if (eventName != null) + { + this.EventName = eventName; + } + + if (eventValue != null) + { + this.EventValue = new ValueExpression(eventValue); + } + + this.BubbleEvent = new BoolExpression(bubble); } /// @@ -41,11 +47,7 @@ public EmitEvent(string eventName = null, string eventValue = null, bool bubble /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets the name of the event to emit. @@ -54,7 +56,7 @@ public string Disabled /// The name of the event to emit. /// [JsonProperty("eventName")] - public string EventName { get; set; } + public StringExpression EventName { get; set; } /// /// Gets or sets the memory property path to use to get the value to send as part of the event. @@ -63,11 +65,7 @@ public string Disabled /// The memory property path to use to get the value to send as part of the event. /// [JsonProperty("eventValue")] - public string EventValue - { - get { return eventValue?.ToString(); } - set { this.eventValue = (value != null) ? new ExpressionEngine().Parse(value) : null; } - } + public ValueExpression EventValue { get; set; } /// /// Gets or sets a value indicating whether the event should bubble to parents or not. @@ -76,7 +74,7 @@ public string EventValue /// A value indicating whether gets or sets whether the event should bubble to parents or not. /// [JsonProperty("bubbleEvent")] - public bool BubbleEvent { get; set; } + public BoolExpression BubbleEvent { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -85,27 +83,31 @@ public string EventValue throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } - var handled = false; - if (eventValue != null) + bool handled; + var eventName = EventName?.GetValue(dcState); + var bubbleEvent = BubbleEvent.GetValue(dcState); + if (EventValue != null) { - var (value, valueError) = this.eventValue.TryEvaluate(dc.GetState()); + var (value, valueError) = this.EventValue.TryGetValue(dcState); if (valueError == null) { - handled = await dc.EmitEventAsync(EventName, value, BubbleEvent, false, cancellationToken).ConfigureAwait(false); + handled = await dc.EmitEventAsync(eventName, value, bubbleEvent, false, cancellationToken).ConfigureAwait(false); } else { - throw new Exception($"Expression evaluation resulted in an error. Expression: {eventValue.ToString()}. Error: {valueError}"); + throw new Exception($"Expression evaluation resulted in an error. Expression: {EventValue.ToString()}. Error: {valueError}"); } } else { - handled = await dc.EmitEventAsync(EventName, EventValue, BubbleEvent, false, cancellationToken).ConfigureAwait(false); + handled = await dc.EmitEventAsync(eventName, EventValue, bubbleEvent, false, cancellationToken).ConfigureAwait(false); } return await dc.EndDialogAsync(handled, cancellationToken).ConfigureAwait(false); @@ -113,7 +115,7 @@ public string EventValue protected override string OnComputeId() { - return $"{this.GetType().Name}[{EventName ?? string.Empty}]"; + return $"{this.GetType().Name}[{EventName.ToString() ?? string.Empty}]"; } } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EndDialog.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EndDialog.cs index 3ec7cadc9d..8aa1539733 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EndDialog.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EndDialog.cs @@ -18,18 +18,15 @@ public class EndDialog : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.EndDialog"; - private Expression value; - private Expression disabled; - [JsonConstructor] - public EndDialog(string value = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) + public EndDialog(object value = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() { this.RegisterSourceLocation(callerPath, callerLine); - if (!string.IsNullOrEmpty(value)) + if (value != null) { - this.Value = value; + this.Value = new ValueExpression(value); } } @@ -43,11 +40,7 @@ public EndDialog(string value = null, [CallerFilePath] string callerPath = "", [ /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets a value expression for the result to be returned to the caller. @@ -56,11 +49,7 @@ public string Disabled /// A value expression for the result to be returned to the caller. /// [JsonProperty("value")] - public string Value - { - get { return value?.ToString(); } - set { this.value = (value != null) ? new ExpressionEngine().Parse(value) : null; } - } + public ValueExpression Value { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -69,14 +58,16 @@ public string Value throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } if (this.Value != null) { - var (result, error) = this.value.TryEvaluate(dc.GetState()); + var (result, error) = this.Value.TryGetValue(dcState); return await EndParentDialogAsync(dc, result, cancellationToken).ConfigureAwait(false); } @@ -104,7 +95,7 @@ public string Value protected override string OnComputeId() { - return $"{this.GetType().Name}({this.Value ?? string.Empty})"; + return $"{this.GetType().Name}({this.Value?.ToString() ?? string.Empty})"; } } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EndTurn.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EndTurn.cs index cfaef9d4cb..eea83a50cd 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EndTurn.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/EndTurn.cs @@ -18,8 +18,6 @@ public class EndTurn : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.EndTurn"; - private Expression disabled; - [JsonConstructor] public EndTurn([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() @@ -38,11 +36,7 @@ public EndTurn([CallerFilePath] string callerPath = "", [CallerLineNumber] int c /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } public override Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -51,7 +45,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return dc.EndDialogAsync(cancellationToken: cancellationToken); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ForEach.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ForEach.cs index df66000742..68012e58c2 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ForEach.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ForEach.cs @@ -23,8 +23,6 @@ public class Foreach : ActionScope private const string INDEX = "dialog.foreach.index"; private const string VALUE = "dialog.foreach.value"; - private Expression disabled; - [JsonConstructor] public Foreach([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) : base() @@ -42,11 +40,7 @@ public Foreach([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] i /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets property path expression to the collection of items. @@ -55,7 +49,7 @@ public string Disabled /// Property path expression to the collection of items. /// [JsonProperty("itemsProperty")] - public string ItemsProperty { get; set; } + public StringExpression ItemsProperty { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -64,12 +58,14 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } - dc.GetState().SetValue(INDEX, -1); + dcState.SetValue(INDEX, -1); return await this.NextItemAsync(dc, cancellationToken).ConfigureAwait(false); } @@ -91,17 +87,16 @@ protected override async Task OnEndOfActionsAsync(DialogContex protected virtual async Task NextItemAsync(DialogContext dc, CancellationToken cancellationToken = default) { // Get list information - var itemsProperty = new ExpressionEngine().Parse(this.ItemsProperty); - var (itemList, error) = itemsProperty.TryEvaluate(dc.GetState()); - var list = JArray.FromObject(itemList); - var index = dc.GetState().GetIntValue(INDEX); + var dcState = dc.GetState(); + var list = dcState.GetValue(this.ItemsProperty.GetValue(dcState)); + var index = dcState.GetIntValue(INDEX); // Next item if (++index < list.Count) { // Persist index and value - dc.GetState().SetValue(VALUE, list[index]); - dc.GetState().SetValue(INDEX, index); + dcState.SetValue(VALUE, list[index]); + dcState.SetValue(INDEX, index); // Start loop return await this.BeginActionAsync(dc, 0, cancellationToken).ConfigureAwait(false); diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ForEachPage.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ForEachPage.cs index a3ea883dd0..31f09c1380 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ForEachPage.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ForEachPage.cs @@ -24,8 +24,6 @@ public class ForeachPage : ActionScope private const string FOREACHPAGE = "dialog.foreach.page"; private const string FOREACHPAGEINDEX = "dialog.foreach.pageindex"; - - private Expression disabled; [JsonConstructor] public ForeachPage([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) @@ -44,18 +42,14 @@ public ForeachPage([CallerFilePath] string sourceFilePath = "", [CallerLineNumbe /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } // Expression used to compute the list that should be enumerated. [JsonProperty("itemsProperty")] - public string ItemsProperty { get; set; } + public StringExpression ItemsProperty { get; set; } [JsonProperty("pageSize")] - public int PageSize { get; set; } = 10; + public IntExpression PageSize { get; set; } = 10; public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -64,7 +58,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -94,20 +90,20 @@ protected override string OnComputeId() private async Task NextPageAsync(DialogContext dc, CancellationToken cancellationToken) { - Expression itemsProperty = new ExpressionEngine().Parse(this.ItemsProperty); - int pageIndex = dc.GetState().GetIntValue(FOREACHPAGEINDEX, 0); - int pageSize = this.PageSize; + var dcState = dc.GetState(); + int pageIndex = dcState.GetIntValue(FOREACHPAGEINDEX, 0); + int pageSize = this.PageSize.GetValue(dcState); int itemOffset = pageSize * pageIndex; - var (items, error) = itemsProperty.TryEvaluate(dc.GetState()); - if (error == null) + var itemsProperty = this.ItemsProperty.GetValue(dcState); + if (dcState.TryGetValue(itemsProperty, out object items)) { var page = this.GetPage(items, itemOffset, pageSize); if (page.Any()) { - dc.GetState().SetValue(FOREACHPAGE, page); - dc.GetState().SetValue(FOREACHPAGEINDEX, ++pageIndex); + dcState.SetValue(FOREACHPAGE, page); + dcState.SetValue(FOREACHPAGEINDEX, ++pageIndex); return await this.BeginActionAsync(dc, 0, cancellationToken).ConfigureAwait(false); } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GetActivityMembers.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GetActivityMembers.cs index 9ade962339..43dab1f7eb 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GetActivityMembers.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GetActivityMembers.cs @@ -18,9 +18,6 @@ public class GetActivityMembers : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.GetActivityMembers"; - private Expression activityId; - private Expression disabled; - [JsonConstructor] public GetActivityMembers([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() @@ -38,11 +35,7 @@ public GetActivityMembers([CallerFilePath] string callerPath = "", [CallerLineNu /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets property path to put the value in. @@ -51,7 +44,7 @@ public string Disabled /// Property path to put the value in. /// [JsonProperty("property")] - public string Property { get; set; } + public StringExpression Property { get; set; } /// /// Gets or sets the expression to get the value to put into property path. @@ -60,11 +53,7 @@ public string Disabled /// The expression to get the value to put into property path. If this is missing, then the current turn Activity.id will be used. /// [JsonProperty("activityId")] - public string ActivityId - { - get { return activityId?.ToString(); } - set { this.activityId = (value != null) ? new ExpressionEngine().Parse(value) : null; } - } + public StringExpression ActivityId { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -72,8 +61,10 @@ public string ActivityId { throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } + + var dcState = dc.GetState(); - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -85,9 +76,9 @@ public string ActivityId } string id = dc.Context.Activity.Id; - if (this.activityId != null) + if (this.ActivityId != null) { - var (value, valueError) = this.activityId.TryEvaluate(dc.GetState()); + var (value, valueError) = this.ActivityId.TryGetValue(dcState); if (valueError != null) { throw new Exception($"Expression evaluation resulted in an error. Expression: {this.ActivityId}. Error: {valueError}"); @@ -98,14 +89,14 @@ public string ActivityId var result = await bfAdapter.GetActivityMembersAsync(dc.Context, id, cancellationToken).ConfigureAwait(false); - dc.GetState().SetValue(this.Property, result); + dcState.SetValue(this.Property.GetValue(dcState), result); return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false); } protected override string OnComputeId() { - return $"{this.GetType().Name}[{this.ActivityId ?? string.Empty},{this.Property ?? string.Empty}]"; + return $"{this.GetType().Name}[{this.ActivityId?.ToString() ?? string.Empty},{this.Property ?? string.Empty}]"; } } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GetConversationMembers.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GetConversationMembers.cs index 50ca5097d4..75aa7e4404 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GetConversationMembers.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GetConversationMembers.cs @@ -18,8 +18,6 @@ public class GetConversationMembers : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.GetConversationMembers"; - private Expression disabled; - [JsonConstructor] public GetConversationMembers([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() @@ -37,11 +35,7 @@ public GetConversationMembers([CallerFilePath] string callerPath = "", [CallerLi /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets property path to put the value in. @@ -50,7 +44,7 @@ public string Disabled /// Property path to put the value in. /// [JsonProperty("property")] - public string Property { get; set; } + public StringExpression Property { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -59,7 +53,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -74,7 +70,7 @@ public string Disabled if (this.Property != null) { - dc.GetState().SetValue(this.Property, result); + dcState.SetValue(this.Property.GetValue(dcState), result); } return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false); diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GotoAction.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GotoAction.cs index 96490d4c60..f177b5f542 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GotoAction.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/GotoAction.cs @@ -18,8 +18,6 @@ public class GotoAction : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.GotoAction"; - private Expression disabled; - public GotoAction(string actionId = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { this.RegisterSourceLocation(callerPath, callerLine); @@ -30,7 +28,7 @@ public GotoAction(string actionId = null, [CallerFilePath] string callerPath = " /// Gets or sets the action Id to goto. /// /// The action Id. - public string ActionId { get; set; } + public StringExpression ActionId { get; set; } /// /// Gets or sets an optional expression which if is true will disable this action. @@ -42,11 +40,7 @@ public GotoAction(string actionId = null, [CallerFilePath] string callerPath = " /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -55,7 +49,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -64,7 +60,7 @@ public string Disabled var actionScopeResult = new ActionScopeResult() { ActionScopeCommand = ActionScopeCommands.GotoAction, - ActionId = this.ActionId ?? throw new ArgumentNullException(nameof(ActionId)) + ActionId = this.ActionId?.GetValue(dcState) ?? throw new ArgumentNullException(nameof(ActionId)) }; return await dc.EndDialogAsync(result: actionScopeResult, cancellationToken: cancellationToken).ConfigureAwait(false); diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/HttpRequest.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/HttpRequest.cs index 26abfcfafb..e01c159a91 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/HttpRequest.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/HttpRequest.cs @@ -10,9 +10,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -using Microsoft.Bot.Builder.Dialogs.Adaptive.Templates; using Microsoft.Bot.Builder.TraceExtensions; -using Microsoft.Bot.Expressions; using Microsoft.Bot.Schema; using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -28,15 +26,13 @@ public class HttpRequest : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.HttpRequest"; - private Expression disabled; - - public HttpRequest(HttpMethod method, string url, string inputProperty, Dictionary headers = null, JObject body = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) + public HttpRequest(HttpMethod method, string url, Dictionary headers = null, object body = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { this.RegisterSourceLocation(callerPath, callerLine); this.Method = method; this.Url = url ?? throw new ArgumentNullException(nameof(url)); this.Headers = headers; - this.Body = body; + this.Body = JToken.FromObject(body); } [JsonConstructor] @@ -111,27 +107,51 @@ public enum HttpMethod /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } + /// + /// Gets or sets the HttpMethod to use. + /// + /// + /// HttpMethod. + /// [JsonConverter(typeof(StringEnumConverter))] [JsonProperty("method")] public HttpMethod Method { get; set; } + /// + /// Gets or sets the Url. + /// + /// url. [JsonProperty("url")] - public string Url { get; set; } + public StringExpression Url { get; set; } + /// + /// Gets or sets headers. + /// + /// + /// Headers. + /// [JsonProperty("headers")] - public Dictionary Headers { get; set; } + public Dictionary Headers { get; set; } + /// + /// Gets or sets body payload. + /// + /// + /// Body payload. + /// [JsonProperty("body")] - public JToken Body { get; set; } + public ValueExpression Body { get; set; } + /// + /// Gets or sets the ResponseType. + /// + /// + /// The ResponseType. + /// [JsonProperty("responseType")] - public ResponseTypes ResponseType { get; set; } = ResponseTypes.Json; + public EnumExpression ResponseType { get; set; } = ResponseTypes.Json; /// /// Gets or sets the property expression to store the HTTP response in. @@ -145,7 +165,7 @@ public string Disabled /// The property expression to store the HTTP response in. /// [JsonProperty("resultProperty")] - public string ResultProperty { get; set; } + public StringExpression ResultProperty { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -154,7 +174,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -167,13 +189,22 @@ public string Disabled JToken instanceBody = null; if (this.Body != null) { - instanceBody = (JToken)this.Body.DeepClone(); + var (body, err) = this.Body.TryGetValue(dcState); + if (err != null) + { + throw new ArgumentException(err); + } + + instanceBody = (JToken)JToken.FromObject(body).DeepClone(); } - var instanceHeaders = Headers == null ? null : new Dictionary(Headers); - var instanceUrl = this.Url; + var instanceHeaders = Headers == null ? null : Headers.ToDictionary(kv => kv.Key, kv => kv.Value.GetValue(dcState)); - instanceUrl = await new TextTemplate(this.Url).BindToData(dc.Context, dc.GetState()).ConfigureAwait(false); + var (instanceUrl, instanceUrlError) = this.Url.TryGetValue(dcState); + if (instanceUrlError != null) + { + throw new ArgumentException(instanceUrlError); + } // Bind each string token to the data in state if (instanceBody != null) @@ -186,9 +217,7 @@ public string Disabled { foreach (var unit in instanceHeaders) { - client.DefaultRequestHeaders.Add( - await new TextTemplate(unit.Key).BindToData(dc.Context, dc.GetState()), - await new TextTemplate(unit.Value).BindToData(dc.Context, dc.GetState())); + client.DefaultRequestHeaders.TryAddWithoutValidation(unit.Key, unit.Value); } } @@ -266,7 +295,7 @@ public string Disabled object content = (object)await response.Content.ReadAsStringAsync(); - switch (this.ResponseType) + switch (this.ResponseType.GetValue(dcState)) { case ResponseTypes.Activity: var activity = JsonConvert.DeserializeObject((string)content); @@ -306,7 +335,7 @@ public string Disabled if (this.ResultProperty != null) { - dc.GetState().SetValue(this.ResultProperty, requestResult); + dcState.SetValue(this.ResultProperty.GetValue(dcState), requestResult); } // return the actionResult as the result of this operation @@ -320,6 +349,8 @@ protected override string OnComputeId() private async Task ReplaceJTokenRecursively(DialogContext dc, JToken token) { + var dcState = dc.GetState(); + switch (token.Type) { case JTokenType.Object: @@ -331,7 +362,8 @@ private async Task ReplaceJTokenRecursively(DialogContext dc, JToken token) break; case JTokenType.Array: - foreach (var child in token.Children()) + // NOTE: ToList() is required because JToken.Replace will break the enumeration. + foreach (var child in token.Children().ToList()) { await ReplaceJTokenRecursively(dc, child); } @@ -348,17 +380,10 @@ private async Task ReplaceJTokenRecursively(DialogContext dc, JToken token) var text = token.ToString(); // if it is a "{bindingpath}" then run through expression engine and treat as a value - if (text.StartsWith("{") && text.EndsWith("}")) - { - text = text.Trim('{', '}'); - var (val, error) = new ExpressionEngine().Parse(text).TryEvaluate(dc.GetState()); - token.Replace(new JValue(val)); - } - else + var (result, error) = new ValueExpression(text).TryGetValue(dcState); + if (error == null) { - // use text template binding to bind in place to a string - var temp = await new TextTemplate(text).BindToData(dc.Context, dc.GetState()); - token.Replace(new JValue(temp)); + token.Replace(JToken.FromObject(result)); } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/IfCondition.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/IfCondition.cs index 3651e13d65..d1b38eea61 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/IfCondition.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/IfCondition.cs @@ -20,9 +20,6 @@ public class IfCondition : Dialog, IDialogDependencies [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.IfCondition"; - private Expression condition; - private Expression disabled; - private ActionScope trueScope; private ActionScope falseScope; @@ -43,11 +40,7 @@ public IfCondition([CallerFilePath] string sourceFilePath = "", [CallerLineNumbe /// The memory expression. /// [JsonProperty("condition")] - public string Condition - { - get { return condition?.ToString(); } - set { condition = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Condition { get; set; } = false; /// /// Gets or sets an optional expression which if is true will disable this action. @@ -59,11 +52,7 @@ public string Condition /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } [JsonProperty("actions")] public List Actions { get; set; } = new List(); @@ -109,8 +98,10 @@ public virtual IEnumerable GetDependencies() { throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } + + var dcState = dc.GetState(); - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -118,9 +109,8 @@ public virtual IEnumerable GetDependencies() // Ensure planning context if (dc is SequenceContext planning) { - var (value, error) = condition.TryEvaluate(dc.GetState()); - var conditionResult = error == null && value != null && (bool)value; - if (conditionResult == true && TrueScope.Actions.Any()) + var (conditionResult, error) = this.Condition.TryGetValue(dcState); + if (error == null && conditionResult == true && TrueScope.Actions.Any()) { // replace dialog with If True Action Scope return await dc.ReplaceDialogAsync(this.TrueScope.Id, cancellationToken: cancellationToken).ConfigureAwait(false); diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/InitProperty.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/InitProperty.cs index 53f2b97052..4bcb5ae460 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/InitProperty.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/InitProperty.cs @@ -19,8 +19,6 @@ public class InitProperty : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.InitProperty"; - private Expression disabled; - [JsonConstructor] public InitProperty([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() @@ -38,11 +36,7 @@ public InitProperty([CallerFilePath] string callerPath = "", [CallerLineNumber] /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets property path to initialize. @@ -51,7 +45,7 @@ public string Disabled /// Property path to initialize. /// [JsonProperty("property")] - public string Property { get; set; } + public StringExpression Property { get; set; } /// /// Gets or sets type, either Array or Object. @@ -69,7 +63,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -77,13 +73,15 @@ public string Disabled // Ensure planning context if (dc is SequenceContext planning) { + var state = dcState; + switch (Type.ToLower()) { case "array": - dc.GetState().SetValue(this.Property, new JArray()); + state.SetValue(this.Property.GetValue(state), new JArray()); break; case "object": - dc.GetState().SetValue(this.Property, new JObject()); + state.SetValue(this.Property.GetValue(state), new JObject()); break; } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/LogAction.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/LogAction.cs index d4cdea4054..a3279aa046 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/LogAction.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/LogAction.cs @@ -21,8 +21,6 @@ public class LogAction : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.LogAction"; - private Expression disabled; - [JsonConstructor] public LogAction(string text = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { @@ -43,11 +41,7 @@ public LogAction(string text = null, [CallerFilePath] string callerPath = "", [C /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets lG expression to log. @@ -65,14 +59,14 @@ public string Disabled /// Whether a TraceActivity will be sent in addition to console log. /// [JsonProperty("traceActivity")] - public bool TraceActivity { get; set; } = false; + public BoolExpression TraceActivity { get; set; } = false; /// /// Gets or sets a label to use when describing a trace activity. /// /// The label to use. (default is the id of the action). [JsonProperty] - public string Label { get; set; } + public StringExpression Label { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -81,18 +75,20 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } - var text = await Text.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false); + var text = await Text.BindToData(dc.Context, dcState).ConfigureAwait(false); System.Diagnostics.Trace.TraceInformation(text); - if (this.TraceActivity) + if (this.TraceActivity.GetValue(dcState)) { - var traceActivity = Activity.CreateTraceActivity(name: "Log", valueType: "Text", value: text, label: this.Label ?? dc.Parent?.ActiveDialog?.Id); + var traceActivity = Activity.CreateTraceActivity(name: "Log", valueType: "Text", value: text, label: this.Label?.GetValue(dcState) ?? dc.Parent?.ActiveDialog?.Id); await dc.Context.SendActivityAsync(traceActivity, cancellationToken).ConfigureAwait(false); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/PropertyAssignment.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/PropertyAssignment.cs index df0fcbf33b..e3e57532be 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/PropertyAssignment.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/PropertyAssignment.cs @@ -6,7 +6,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions { /// - /// Property Assignment. + /// Property Assignment (used in SetProperty and SetProperties actions). /// public class PropertyAssignment { @@ -15,13 +15,13 @@ public class PropertyAssignment /// /// A property path expression. [JsonProperty("property")] - public string Property { get; set; } + public StringExpression Property { get; set; } /// /// Gets or sets the value to set. /// /// Value expression. [JsonProperty("value")] - public string Value { get; set; } + public ValueExpression Value { get; set; } } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/RepeatDialog.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/RepeatDialog.cs index 719de777f0..88601f38c5 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/RepeatDialog.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/RepeatDialog.cs @@ -19,8 +19,6 @@ public class RepeatDialog : BaseInvokeDialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.RepeatDialog"; - private Expression disabled; - [JsonConstructor] public RepeatDialog([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() @@ -38,11 +36,7 @@ public RepeatDialog([CallerFilePath] string callerPath = "", [CallerLineNumber] /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -51,7 +45,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -61,17 +57,17 @@ public string Disabled var targetDialogId = dc.Parent.ActiveDialog.Id; - var repeatedIds = dc.GetState().GetValue>(TurnPath.REPEATEDIDS, () => new List()); + var repeatedIds = dcState.GetValue>(TurnPath.REPEATEDIDS, () => new List()); if (repeatedIds.Contains(targetDialogId)) { throw new ArgumentException($"Recursive loop detected, {targetDialogId} cannot be repeated twice in one turn."); } repeatedIds.Add(targetDialogId); - dc.GetState().SetValue(TurnPath.REPEATEDIDS, repeatedIds); + dcState.SetValue(TurnPath.REPEATEDIDS, repeatedIds); // set the activity processed state (default is true) - dc.GetState().SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed); + dcState.SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed); var turnResult = await dc.Parent.ReplaceDialogAsync(dc.Parent.ActiveDialog.Id, boundOptions, cancellationToken).ConfigureAwait(false); turnResult.ParentEnded = true; diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ReplaceDialog.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ReplaceDialog.cs index 4d16a83d3c..7129e15af6 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ReplaceDialog.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ReplaceDialog.cs @@ -19,10 +19,8 @@ public class ReplaceDialog : BaseInvokeDialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.ReplaceDialog"; - private Expression disabled; - [JsonConstructor] - public ReplaceDialog(string dialogIdToCall = null, IDictionary options = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) + public ReplaceDialog(string dialogIdToCall = null, object options = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base(dialogIdToCall, options) { this.RegisterSourceLocation(callerPath, callerLine); @@ -38,11 +36,7 @@ public ReplaceDialog(string dialogIdToCall = null, IDictionary o /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -51,7 +45,9 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -62,7 +58,7 @@ public string Disabled var boundOptions = BindOptions(dc, options); // set the activity processed state (default is true) - dc.GetState().SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed); + dcState.SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed); // replace dialog with bound options passed in as the options return await dc.ReplaceDialogAsync(dialog.Id, options: boundOptions, cancellationToken: cancellationToken).ConfigureAwait(false); diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SendActivity.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SendActivity.cs index abd25e42d7..40dbd203eb 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SendActivity.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SendActivity.cs @@ -21,8 +21,6 @@ public class SendActivity : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.SendActivity"; - private Expression disabled; - public SendActivity(Activity activity, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { this.RegisterSourceLocation(callerPath, callerLine); @@ -46,11 +44,7 @@ public SendActivity(string text = null, [CallerFilePath] string callerPath = "", /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets template for the activity. @@ -68,12 +62,14 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } - var activity = await Activity.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false); + var activity = await Activity.BindToData(dc.Context, dcState).ConfigureAwait(false); ResourceResponse response = null; if (activity.Type != "message" || !string.IsNullOrEmpty(activity.Text) diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SetProperties.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SetProperties.cs index 606a773fda..10249aa2d3 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SetProperties.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SetProperties.cs @@ -20,8 +20,6 @@ public class SetProperties : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.SetProperties"; - private Expression disabled; - [JsonConstructor] public SetProperties([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() @@ -39,11 +37,7 @@ public SetProperties([CallerFilePath] string callerPath = "", [CallerLineNumber] /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets additional property assignments. @@ -61,21 +55,22 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } foreach (var propValue in this.Assignments) { - var valexp = new ExpressionEngine().Parse(propValue.Value); - var (value, valueError) = valexp.TryEvaluate(dc.GetState()); + var (value, valueError) = propValue.Value.TryGetValue(dcState); if (valueError != null) { - throw new Exception($"Expression evaluation resulted in an error. Expression: {valexp.ToString()}. Error: {valueError}"); + throw new Exception($"Expression evaluation resulted in an error. Expression: {propValue.Value.ToString()}. Error: {valueError}"); } - dc.GetState().SetValue(propValue.Property, value); + dcState.SetValue(propValue.Property.GetValue(dcState), value); } return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SetProperty.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SetProperty.cs index fe5cdcaf46..407ceee36e 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SetProperty.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SetProperty.cs @@ -5,6 +5,7 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; +using Microsoft.Bot.Builder.Dialogs.Declarative; using Microsoft.Bot.Expressions; using Newtonsoft.Json; @@ -18,9 +19,6 @@ public class SetProperty : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.SetProperty"; - private Expression value; - private Expression disabled; - [JsonConstructor] public SetProperty([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base() @@ -38,11 +36,7 @@ public SetProperty([CallerFilePath] string callerPath = "", [CallerLineNumber] i /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets property path to put the value in. @@ -51,7 +45,7 @@ public string Disabled /// Property path to put the value in. /// [JsonProperty("property")] - public string Property { get; set; } + public StringExpression Property { get; set; } /// /// Gets or sets the expression to get the value to put into property path. @@ -60,11 +54,7 @@ public string Disabled /// The expression to get the value to put into property path. /// [JsonProperty("value")] - public string Value - { - get { return value?.ToString(); } - set { this.value = (value != null) ? new ExpressionEngine().Parse(value) : null; } - } + public ValueExpression Value { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -73,21 +63,28 @@ public string Value throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + if (this.Disabled != null && this.Disabled.GetValue(dcState)) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } // SetProperty evaluates the "Value" expression and returns it as the result of the dialog - var (value, valueError) = this.value.TryEvaluate(dc.GetState()); - if (valueError != null) + object value = null; + if (this.Value != null) { - throw new Exception($"Expression evaluation resulted in an error. Expression: {this.Value.ToString()}. Error: {valueError}"); + var (val, valueError) = this.Value.TryGetValue(dcState); + if (valueError != null) + { + throw new Exception($"Expression evaluation resulted in an error. Expression: {this.Value.ToString()}. Error: {valueError}"); + } + + value = val; } - dc.GetState().SetValue(this.Property, value); + dcState.SetValue(this.Property.GetValue(dcState), value); - dc.GetState().SetValue(DialogPath.Retries, 0); + dcState.SetValue(DialogPath.Retries, 0); return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SignOutUser.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SignOutUser.cs index 65d7d069f4..f1e3c5b219 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SignOutUser.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SignOutUser.cs @@ -20,9 +20,6 @@ public class SignOutUser : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.SignOutUser"; - private Expression userId; - private Expression disabled; - [JsonConstructor] public SignOutUser([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { @@ -39,29 +36,21 @@ public SignOutUser([CallerFilePath] string callerPath = "", [CallerLineNumber] i /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets the expression which resolves to the activityId to update. /// /// Expression to userId. If there is no expression, then the current user.id will be used. [JsonProperty("userId")] - public string UserId - { - get { return userId?.ToString(); } - set { this.userId = (value != null) ? new ExpressionEngine().Parse(value) : null; } - } + public StringExpression UserId { get; set; } /// /// Gets or sets the name of the OAuth connection. /// /// The name of the OAuth connection. [JsonProperty("connectionName")] - public string ConnectionName { get; set; } + public StringExpression ConnectionName { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -70,24 +59,22 @@ public string UserId throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) - { - return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); - } + var dcState = dc.GetState(); - string userId = null; - var (result, error) = new ExpressionEngine().Parse(this.UserId).TryEvaluate(dc.GetState()); - if (result != null) + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { - userId = result as string; + return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } + string userId = this.UserId?.GetValue(dcState); + if (!(dc.Context.Adapter is IUserTokenProvider adapter)) { throw new InvalidOperationException("SignoutUser(): not supported by the current adapter"); } - await adapter.SignOutUserAsync(dc.Context, this.ConnectionName, (string)userId, cancellationToken).ConfigureAwait(false); + var connectionName = this.ConnectionName?.GetValue(dcState); + await adapter.SignOutUserAsync(dc.Context, connectionName, (string)userId, cancellationToken).ConfigureAwait(false); return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SwitchCondition.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SwitchCondition.cs index f130892276..d89ed0f7d9 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SwitchCondition.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/SwitchCondition.cs @@ -22,8 +22,6 @@ public class SwitchCondition : Dialog, IDialogDependencies private Dictionary caseExpressions = null; - private Expression condition; - private Expression disabled; private ActionScope defaultScope; [JsonConstructor] @@ -34,17 +32,13 @@ public SwitchCondition([CallerFilePath] string callerPath = "", [CallerLineNumbe } /// - /// Gets or sets condition expression against memory Example: "user.age > 18". + /// Gets or sets value expression against memory Example: "user.age". /// /// - /// Condition expression against memory Example: "user.age > 18". + /// Value Expression against memory. This value expression will be combined with value expression in case statements to make a bool expression. /// [JsonProperty("condition")] - public string Condition - { - get { return condition?.ToString(); } - set { condition = (value != null) ? new ExpressionEngine().Parse(value) : null; } - } + public ValueExpression Condition { get; set; } /// /// Gets or sets an optional expression which if is true will disable this action. @@ -56,11 +50,7 @@ public string Condition /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets default case. @@ -113,7 +103,9 @@ public virtual IEnumerable GetDependencies() throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -127,13 +119,13 @@ public virtual IEnumerable GetDependencies() { this.caseExpressions = new Dictionary(); - foreach (var c in this.Cases) + foreach (var cse in this.Cases) { // Values for cases are always coerced to string - var caseCondition = Expression.EqualsExpression(this.condition, c.CreateValueExpression()); + var caseCondition = Expression.EqualsExpression(this.Condition.ToExpression(), cse.CreateValueExpression()); // Map of expression to actions - this.caseExpressions[c.Value] = caseCondition; + this.caseExpressions[cse.Value] = caseCondition; } } } @@ -142,7 +134,7 @@ public virtual IEnumerable GetDependencies() foreach (var caseScope in this.Cases) { - var (value, error) = this.caseExpressions[caseScope.Value].TryEvaluate(dc.GetState()); + var (value, error) = this.caseExpressions[caseScope.Value].TryEvaluate(dcState); if (error != null) { diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/TraceActivity.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/TraceActivity.cs index dbd83d6670..b36cfcb823 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/TraceActivity.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/TraceActivity.cs @@ -19,8 +19,6 @@ public class TraceActivity : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.TraceActivity"; - private Expression disabled; - [JsonConstructor] public TraceActivity([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { @@ -37,11 +35,7 @@ public TraceActivity([CallerFilePath] string callerPath = "", [CallerLineNumber] /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets name of the trace activity. @@ -50,7 +44,7 @@ public string Disabled /// Name of the trace activity. /// [JsonProperty("name")] - public string Name { get; set; } + public StringExpression Name { get; set; } /// /// Gets or sets value type of the trace activity. @@ -59,7 +53,7 @@ public string Disabled /// Value type of the trace activity. /// [JsonProperty("valueType")] - public string ValueType { get; set; } + public StringExpression ValueType { get; set; } /// /// Gets or sets value expression to send as the value. @@ -68,14 +62,14 @@ public string Disabled /// Property binding to memory to send as the value. /// [JsonProperty("value")] - public string Value { get; set; } + public ValueExpression Value { get; set; } /// /// Gets or sets a label to use when describing a trace activity. /// /// The label to use. (default will use Name or parent dialog.id). [JsonProperty] - public string Label { get; set; } + public StringExpression Label { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -84,22 +78,34 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } object value = null; - if (!string.IsNullOrEmpty(this.Value)) + if (this.Value != null) { - value = dc.GetState().GetValue(this.Value); + var (val, valError) = this.Value.TryGetValue(dcState); + if (valError != null) + { + throw new Exception(valError); + } + + value = val; } else { - value = dc.GetState().GetMemorySnapshot(); + value = dcState.GetMemorySnapshot(); } - var traceActivity = Activity.CreateTraceActivity(this.Name ?? "Trace", valueType: this.ValueType ?? "State", value: value, label: this.Label ?? this.Name ?? dc.Parent?.ActiveDialog?.Id); + var name = this.Name?.GetValue(dcState); + var valueType = this.ValueType?.GetValue(dcState); + var label = this.Label?.GetValue(dcState); + + var traceActivity = Activity.CreateTraceActivity(name ?? "Trace", valueType: valueType ?? "State", value: value, label: label ?? name ?? dc.Parent?.ActiveDialog?.Id); await dc.Context.SendActivityAsync(traceActivity, cancellationToken).ConfigureAwait(false); return await dc.EndDialogAsync(traceActivity, cancellationToken: cancellationToken).ConfigureAwait(false); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/UpdateActivity.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/UpdateActivity.cs index c561e29689..7f5851fe57 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/UpdateActivity.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/UpdateActivity.cs @@ -20,9 +20,6 @@ public class UpdateActivity : Dialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.UpdateActivity"; - private Expression activityId; - private Expression disabled; - public UpdateActivity(Activity activity, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { this.RegisterSourceLocation(callerPath, callerLine); @@ -46,11 +43,7 @@ public UpdateActivity(string text = null, [CallerFilePath] string callerPath = " /// A boolean expression. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// /// Gets or sets template for the activity. @@ -66,11 +59,7 @@ public string Disabled /// /// Expression to activityId. [JsonProperty("activityId")] - public string ActivityId - { - get { return activityId.ToString(); } - set { activityId = new ExpressionEngine().Parse(value); } - } + public StringExpression ActivityId { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -79,13 +68,15 @@ public string ActivityId throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } - var activity = await Activity.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false); - var (result, error) = activityId.TryEvaluate(dc.GetState()); + var activity = await Activity.BindToData(dc.Context, dcState).ConfigureAwait(false); + var (result, error) = this.ActivityId.TryGetValue(dcState); if (error != null) { throw new ArgumentException(error); diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/AdaptiveComponentRegistration.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/AdaptiveComponentRegistration.cs index ef262180e9..d5f2e07d8a 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/AdaptiveComponentRegistration.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/AdaptiveComponentRegistration.cs @@ -5,6 +5,7 @@ using Microsoft.Bot.Builder.AI.Luis; using Microsoft.Bot.Builder.Dialogs.Adaptive.Actions; using Microsoft.Bot.Builder.Dialogs.Adaptive.Conditions; +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; using Microsoft.Bot.Builder.Dialogs.Adaptive.Generators; using Microsoft.Bot.Builder.Dialogs.Adaptive.Input; using Microsoft.Bot.Builder.Dialogs.Adaptive.QnA; @@ -14,6 +15,7 @@ using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing; using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing.Actions; using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing.TestActions; +using Microsoft.Bot.Builder.Dialogs.Choices; using Microsoft.Bot.Builder.Dialogs.Debugging; using Microsoft.Bot.Builder.Dialogs.Declarative; using Microsoft.Bot.Builder.Dialogs.Declarative.Converters; @@ -21,6 +23,7 @@ using Microsoft.Bot.Builder.Dialogs.Declarative.Resolvers; using Microsoft.Bot.Builder.Dialogs.Declarative.Types; using Newtonsoft.Json; +using static Microsoft.Bot.Builder.Dialogs.Adaptive.Actions.EditArray; namespace Microsoft.Bot.Builder.Dialogs.Adaptive { @@ -167,8 +170,28 @@ public override IEnumerable GetConverters(ISourceMap sourceMap, I yield return new InterfaceConverter(refResolver, sourceMap, paths); yield return new InterfaceConverter(refResolver, sourceMap, paths); yield return new InterfaceConverter(refResolver, sourceMap, paths); - yield return new ExpressionPropertyConverter(); - yield return new ExpressionPropertyConverter>>(); + + yield return new IntExpressionConverter(); + yield return new NumberExpressionConverter(); + yield return new StringExpressionConverter(); + yield return new ValueExpressionConverter(); + yield return new BoolExpressionConverter(); + yield return new DialogExpressionConverter(refResolver, sourceMap, paths); + + yield return new ObjectExpressionConverter(); + yield return new ObjectExpressionConverter(); + yield return new ObjectExpressionConverter(); + + yield return new ArrayExpressionConverter(); + yield return new ArrayExpressionConverter(); + + yield return new EnumExpressionConverter(); + yield return new EnumExpressionConverter(); + yield return new EnumExpressionConverter(); + yield return new EnumExpressionConverter(); + yield return new EnumExpressionConverter(); + + yield return new ChoiceSetConverter(); yield return new ActivityTemplateConverter(); yield return new JObjectConverter(refResolver); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/AdaptiveDialog.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/AdaptiveDialog.cs index f9f5516c0b..7e028d6a70 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/AdaptiveDialog.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/AdaptiveDialog.cs @@ -153,31 +153,33 @@ public override async Task BeginDialogAsync(DialogContext dc, EnsureDependenciesInstalled(); - if (!dc.GetState().ContainsKey(DialogPath.EventCounter)) + var dcState = dc.GetState(); + + if (!dcState.ContainsKey(DialogPath.EventCounter)) { - dc.GetState().SetValue(DialogPath.EventCounter, 0u); + dcState.SetValue(DialogPath.EventCounter, 0u); } - if (dialogSchema != null && !dc.GetState().ContainsKey(DialogPath.RequiredProperties)) + if (dialogSchema != null && !dcState.ContainsKey(DialogPath.RequiredProperties)) { // RequiredProperties control what properties must be filled in. // Initialize if not present from schema. - dc.GetState().SetValue(DialogPath.RequiredProperties, dialogSchema.Required()); + dcState.SetValue(DialogPath.RequiredProperties, dialogSchema.Required()); } if (needsTracker) { - if (!dc.GetState().ContainsKey(ConditionTracker)) + if (!dcState.ContainsKey(ConditionTracker)) { var parser = Selector.Parser; foreach (var trigger in Triggers) { - if (trigger.RunOnce) + if (trigger.RunOnce && trigger.Condition != null) { - var paths = dc.GetState().TrackPaths(parser.Parse(trigger.Condition).References()); + var paths = dcState.TrackPaths(trigger.Condition.ToExpression().References()); var triggerPath = $"{ConditionTracker}.{trigger.Id}."; - dc.GetState().SetValue(triggerPath + "paths", paths); - dc.GetState().SetValue(triggerPath + "lastRun", 0u); + dcState.SetValue(triggerPath + "paths", paths); + dcState.SetValue(triggerPath + "lastRun", 0u); } } } @@ -303,14 +305,16 @@ protected override async Task OnPostBubbleEventAsync(DialogContext dc, Dia protected virtual async Task ProcessEventAsync(SequenceContext sequenceContext, DialogEvent dialogEvent, bool preBubble, CancellationToken cancellationToken = default(CancellationToken)) { + var dcState = sequenceContext.GetState(); + // Save into turn - sequenceContext.GetState().SetValue(TurnPath.DIALOGEVENT, dialogEvent); + dcState.SetValue(TurnPath.DIALOGEVENT, dialogEvent); EnsureDependenciesInstalled(); // Count of events processed - var count = sequenceContext.GetState().GetValue(DialogPath.EventCounter); - sequenceContext.GetState().SetValue(DialogPath.EventCounter, ++count); + var count = dcState.GetValue(DialogPath.EventCounter); + dcState.SetValue(DialogPath.EventCounter, ++count); // Look for triggered evt var handled = await QueueFirstMatchAsync(sequenceContext, dialogEvent, preBubble, cancellationToken).ConfigureAwait(false); @@ -326,7 +330,7 @@ protected override async Task OnPostBubbleEventAsync(DialogContext dc, Dia switch (dialogEvent.Name) { case AdaptiveEvents.BeginDialog: - if (sequenceContext.GetState().GetBoolValue(TurnPath.ACTIVITYPROCESSED) == false) + if (dcState.GetBoolValue(TurnPath.ACTIVITYPROCESSED) == false) { // Emit leading ActivityReceived event var activityReceivedEvent = new DialogEvent() @@ -355,7 +359,7 @@ protected override async Task OnPostBubbleEventAsync(DialogContext dc, Dia await ProcessEventAsync(sequenceContext, dialogEvent: recognizeUtteranceEvent, preBubble: true, cancellationToken: cancellationToken).ConfigureAwait(false); // Emit leading RecognizedIntent event - var recognized = sequenceContext.GetState().GetValue(TurnPath.RECOGNIZED); + var recognized = dcState.GetValue(TurnPath.RECOGNIZED); var recognizedIntentEvent = new DialogEvent { Name = AdaptiveEvents.RecognizedIntent, @@ -372,7 +376,7 @@ protected override async Task OnPostBubbleEventAsync(DialogContext dc, Dia // process the users uterrance when its continued. if (handled) { - sequenceContext.GetState().SetValue(TurnPath.INTERRUPTED, true); + dcState.SetValue(TurnPath.INTERRUPTED, true); } break; @@ -384,12 +388,12 @@ protected override async Task OnPostBubbleEventAsync(DialogContext dc, Dia // Recognize utterance var recognized = await OnRecognize(sequenceContext, cancellationToken).ConfigureAwait(false); - sequenceContext.GetState().SetValue(TurnPath.RECOGNIZED, recognized); + dcState.SetValue(TurnPath.RECOGNIZED, recognized); var (name, score) = recognized.GetTopScoringIntent(); - sequenceContext.GetState().SetValue(TurnPath.TOPINTENT, name); - sequenceContext.GetState().SetValue(DialogPath.LastIntent, name); - sequenceContext.GetState().SetValue(TurnPath.TOPSCORE, score); + dcState.SetValue(TurnPath.TOPINTENT, name); + dcState.SetValue(DialogPath.LastIntent, name); + dcState.SetValue(TurnPath.TOPSCORE, score); if (Recognizer != null) { @@ -407,7 +411,7 @@ protected override async Task OnPostBubbleEventAsync(DialogContext dc, Dia switch (dialogEvent.Name) { case AdaptiveEvents.BeginDialog: - if (sequenceContext.GetState().GetBoolValue(TurnPath.ACTIVITYPROCESSED) == false) + if (dcState.GetBoolValue(TurnPath.ACTIVITYPROCESSED) == false) { var activityReceivedEvent = new DialogEvent { @@ -450,7 +454,7 @@ protected override async Task OnPostBubbleEventAsync(DialogContext dc, Dia // process the users uterrance when its continued. if (handled) { - sequenceContext.GetState().SetValue(TurnPath.INTERRUPTED, true); + dcState.SetValue(TurnPath.INTERRUPTED, true); } break; @@ -555,6 +559,8 @@ protected async Task OnEndOfActionsAsync(SequenceContext seque // Is the current dialog still on the stack? if (sequenceContext.ActiveDialog != null) { + var dcState = sequenceContext.GetState(); + // Completed actions so continue processing entity queues var handled = await ProcessQueuesAsync(sequenceContext, cancellationToken).ConfigureAwait(false); @@ -566,7 +572,7 @@ protected async Task OnEndOfActionsAsync(SequenceContext seque else if (ShouldEnd(sequenceContext)) { RestoreParentGenerator(sequenceContext.Context); - sequenceContext.GetState().TryGetValue(DefaultResultProperty, out var result); + dcState.TryGetValue(DefaultResultProperty, out var result); return await sequenceContext.EndDialogAsync(result, cancellationToken).ConfigureAwait(false); } @@ -620,6 +626,8 @@ protected async Task OnRecognize(SequenceContext sequenceConte // In order ClearProperties, AssignEntity, ChooseProperties, ChooseEntity, EndOfActions. private async Task ProcessQueuesAsync(SequenceContext sequenceContext, CancellationToken cancellationToken) { + var dcState = sequenceContext.GetState(); + DialogEvent evt; var queues = EntityEvents.Read(sequenceContext); var changed = false; @@ -642,7 +650,7 @@ private async Task ProcessQueuesAsync(SequenceContext sequenceContext, Can entity = new object[] { entity }; } - sequenceContext.GetState().SetValue($"{TurnPath.RECOGNIZED}.entities.{val.Entity.Name}", entity); + dcState.SetValue($"{TurnPath.RECOGNIZED}.entities.{val.Entity.Name}", entity); changed = true; } else if (queues.ChooseProperties.Any()) @@ -663,7 +671,7 @@ private async Task ProcessQueuesAsync(SequenceContext sequenceContext, Can queues.Write(sequenceContext); } - sequenceContext.GetState().SetValue(DialogPath.LastEvent, evt.Name); + dcState.SetValue(DialogPath.LastEvent, evt.Name); var handled = await this.ProcessEventAsync(sequenceContext, dialogEvent: evt, preBubble: true, cancellationToken: cancellationToken).ConfigureAwait(false); if (!handled) { @@ -711,7 +719,7 @@ private void EnsureDependenciesInstalled() { installedDependencies = true; - var id = 0u; + var id = 0; foreach (var trigger in Triggers) { if (trigger is IDialogDependencies depends) @@ -730,7 +738,7 @@ private void EnsureDependenciesInstalled() if (trigger.Priority == null) { // Constant expression defined from order - trigger.Priority = id.ToString(); + trigger.Priority = id; } if (trigger.Id == null) @@ -812,17 +820,19 @@ private void RestoreParentGenerator(ITurnContext context) // Merge new queues into existing queues of ambiguity events private void ProcessEntities(SequenceContext context) { + var dcState = context.GetState(); + if (dialogSchema != null) { - if (context.GetState().TryGetValue(DialogPath.LastEvent, out var lastEvent)) + if (dcState.TryGetValue(DialogPath.LastEvent, out var lastEvent)) { - context.GetState().RemoveValue(DialogPath.LastEvent); + dcState.RemoveValue(DialogPath.LastEvent); } var queues = EntityEvents.Read(context); var entities = NormalizeEntities(context); var utterance = context.Context.Activity?.AsMessageActivity()?.Text; - if (!context.GetState().TryGetValue(DialogPath.ExpectedProperties, out var expected)) + if (!dcState.TryGetValue(DialogPath.ExpectedProperties, out var expected)) { expected = new string[0]; } @@ -833,9 +843,9 @@ private void ProcessEntities(SequenceContext context) var unrecognized = SplitUtterance(utterance, recognized); // TODO: Is this actually useful information? - context.GetState().SetValue(TurnPath.UNRECOGNIZEDTEXT, unrecognized); - context.GetState().SetValue(TurnPath.RECOGNIZEDENTITIES, recognized); - var turn = context.GetState().GetValue(DialogPath.EventCounter); + dcState.SetValue(TurnPath.UNRECOGNIZEDTEXT, unrecognized); + dcState.SetValue(TurnPath.RECOGNIZEDENTITIES, recognized); + var turn = dcState.GetValue(DialogPath.EventCounter); CombineOldEntityToProperties(queues, turn); queues.Write(context); } @@ -873,11 +883,12 @@ private List SplitUtterance(string utterance, List recognize // Combine entity values and $instance meta-data private Dictionary> NormalizeEntities(SequenceContext context) { + var dcState = context.GetState(); var entityToInfo = new Dictionary>(); - var text = context.GetState().GetValue(TurnPath.RECOGNIZED + ".text"); - if (context.GetState().TryGetValue(TurnPath.RECOGNIZED + ".entities", out var entities)) + var text = dcState.GetValue(TurnPath.RECOGNIZED + ".text"); + if (dcState.TryGetValue(TurnPath.RECOGNIZED + ".entities", out var entities)) { - var turn = context.GetState().GetValue(DialogPath.EventCounter); + var turn = dcState.GetValue(DialogPath.EventCounter); var metaData = entities["$instance"]; foreach (var entry in entities) { @@ -1070,6 +1081,7 @@ private IEnumerable RemoveOverlappingPerProperty(IEnumerable AddToQueues(SequenceContext context, Dictionary> entities, string[] expected, EntityEvents queues, string lastEvent) { + var dcState = context.GetState(); var candidates = (from candidate in RemoveOverlappingPerProperty(Candidates(entities, expected)) orderby candidate.IsExpected descending select candidate).ToList(); @@ -1103,7 +1115,7 @@ orderby candidate.IsExpected descending { // Resolve choice and add to queues queues.ChooseProperties.Dequeue(); - context.GetState().SetValue(DialogPath.ExpectedProperties, new List { choice.Property }); + dcState.SetValue(DialogPath.ExpectedProperties, new List { choice.Property }); choice.IsExpected = true; AddMappingToQueue(choice, queues); mapped = true; diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/DialogManager.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/DialogManager.cs index 18eacac28e..bfd682ebce 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/DialogManager.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/DialogManager.cs @@ -22,13 +22,10 @@ public class DialogManager { private const string DIALOGS = "_dialogs"; private const string LASTACCESS = "_lastAccess"; - private DialogSet dialogSet; private string rootDialogId; public DialogManager(Dialog rootDialog = null) { - this.dialogSet = new DialogSet(); - if (rootDialog != null) { this.RootDialog = rootDialog; @@ -63,7 +60,7 @@ public Dialog RootDialog { if (this.rootDialogId != null) { - return this.dialogSet.Find(this.rootDialogId); + return this.Dialogs.Find(this.rootDialogId); } return null; @@ -71,11 +68,11 @@ public Dialog RootDialog set { - this.dialogSet = new DialogSet(); + this.Dialogs = new DialogSet(); if (value != null) { this.rootDialogId = value.Id; - this.dialogSet.Add(value); + this.Dialogs.Add(value); } else { @@ -84,6 +81,13 @@ public Dialog RootDialog } } + /// + /// Gets or sets global dialogs that you want to have be callable. + /// + /// Dialogs set. + [JsonIgnore] + public DialogSet Dialogs { get; set; } = new DialogSet(); + /// /// Gets or sets the DialogStateManagerConfiguration. /// @@ -141,7 +145,7 @@ public Dialog RootDialog DialogState dialogState = await dialogsProperty.GetAsync(context, () => new DialogState(), cancellationToken: cancellationToken).ConfigureAwait(false); // Create DialogContext - var dc = new DialogContext(this.dialogSet, context, dialogState); + var dc = new DialogContext(this.Dialogs, context, dialogState); // set DSM configuration dc.SetStateConfiguration(this.StateConfiguration ?? DialogStateManager.CreateStandardConfiguration(conversationState, userState)); diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/EntityEvents.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/EntityEvents.cs index 1a1a991f5b..2174f3a7a1 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/EntityEvents.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/EntityEvents.cs @@ -46,7 +46,9 @@ public class EntityEvents /// Event queues. public static EntityEvents Read(SequenceContext context) { - if (!context.GetState().TryGetValue(Events, out var queues)) + var dcState = context.GetState(); + + if (!dcState.TryGetValue(Events, out var queues)) { queues = new EntityEvents(); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/Ask.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/Ask.cs index aaf6a0d114..2c9ce411a5 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/Ask.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/Ask.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; @@ -16,8 +17,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions /// Ask for an open-ended response. /// /// - /// This sends an activity and then terminates with in order to allow the parent - /// adaptive dialog to handle the user utterance. + /// This sends an activity and then terminates the turn with . + /// The next activity from the user will then be handled by the parent adaptive dialog. + /// /// It also builds in a model of the properties that are expected in response through . /// is updated as the same question is asked multiple times. /// @@ -25,11 +27,11 @@ public class Ask : SendActivity { [JsonProperty("$kind")] public new const string DeclarativeType = "Microsoft.Ask"; - + [JsonConstructor] public Ask( string text = null, - ExpressionProperty> expectedProperties = null, + ArrayExpression expectedProperties = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) : base(text, callerPath, callerLine) @@ -45,36 +47,38 @@ public Ask( /// Properties expected to be filled by response. /// [JsonProperty("expectedProperties")] - public ExpressionProperty> ExpectedProperties { get; set; } + public ArrayExpression ExpectedProperties { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default) { + var dcState = dc.GetState(); + //get number of retries from memory - if (!dc.GetState().TryGetValue(DialogPath.Retries, out int retries)) + if (!dcState.TryGetValue(DialogPath.Retries, out int retries)) { retries = 0; } - dc.GetState().TryGetValue(TurnPath.DIALOGEVENT, out DialogEvent trigger); + dcState.TryGetValue(TurnPath.DIALOGEVENT, out DialogEvent trigger); - var expected = ExpectedProperties?.GetValue(dc.GetState()); + var expected = this.ExpectedProperties?.GetValue(dcState); if (expected != null - && dc.GetState().TryGetValue(DialogPath.ExpectedProperties, out List lastExpectedProperties) - && !expected.Any(prop => !lastExpectedProperties.Contains(prop)) - && !lastExpectedProperties.Any(prop => !expected.Contains(prop)) - && dc.GetState().TryGetValue(DialogPath.LastTriggerEvent, out DialogEvent lastTrigger) - && lastTrigger.Name.Equals(trigger.Name)) + && dcState.TryGetValue(DialogPath.ExpectedProperties, out List lastExpectedProperties) + && !expected.Any(prop => !lastExpectedProperties.Contains(prop)) + && !lastExpectedProperties.Any(prop => !expected.Contains(prop)) + && dcState.TryGetValue(DialogPath.LastTriggerEvent, out DialogEvent lastTrigger) + && lastTrigger.Name.Equals(trigger.Name)) { - retries++; + retries++; } else { retries = 0; } - dc.GetState().SetValue(DialogPath.Retries, retries); - dc.GetState().SetValue(DialogPath.LastTriggerEvent, trigger); - dc.GetState().SetValue(DialogPath.ExpectedProperties, expected); + dcState.SetValue(DialogPath.Retries, retries); + dcState.SetValue(DialogPath.LastTriggerEvent, trigger); + dcState.SetValue(DialogPath.ExpectedProperties, expected); var result = await base.BeginDialogAsync(dc, options, cancellationToken).ConfigureAwait(false); result.Status = DialogTurnStatus.CompleteAndWait; return result; diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/AttachmentInput.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/AttachmentInput.cs index 7e63a3a1a6..d69be55512 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/AttachmentInput.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/AttachmentInput.cs @@ -38,11 +38,12 @@ public AttachmentInput([CallerFilePath] string callerPath = "", [CallerLineNumbe } [JsonProperty("outputFormat")] - public AttachmentOutputFormat OutputFormat { get; set; } = AttachmentOutputFormat.First; + public EnumExpression OutputFormat { get; set; } = AttachmentOutputFormat.First; protected override Task OnRecognizeInput(DialogContext dc) { - var input = dc.GetState().GetValue>(VALUE_PROPERTY); + var dcState = dc.GetState(); + var input = dcState.GetValue>(VALUE_PROPERTY); var first = input.Count > 0 ? input[0] : null; if (first == null || (string.IsNullOrEmpty(first.ContentUrl) && first.Content == null)) @@ -50,13 +51,13 @@ protected override Task OnRecognizeInput(DialogContext dc) return Task.FromResult(InputState.Unrecognized); } - switch (this.OutputFormat) + switch (this.OutputFormat.GetValue(dcState)) { case AttachmentOutputFormat.All: - dc.GetState().SetValue(VALUE_PROPERTY, input); + dcState.SetValue(VALUE_PROPERTY, input); break; case AttachmentOutputFormat.First: - dc.GetState().SetValue(VALUE_PROPERTY, first); + dcState.SetValue(VALUE_PROPERTY, first); break; } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ChoiceInput.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ChoiceInput.cs index 26a94f14ef..7566f2163b 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ChoiceInput.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ChoiceInput.cs @@ -61,7 +61,7 @@ public ChoiceInput([CallerFilePath] string callerPath = "", [CallerLineNumber] i /// Value Expression or List of choices (string or Choice objects) to present to user. /// [JsonProperty("choices")] - public ChoiceSet Choices { get; set; } + public ObjectExpression Choices { get; set; } /// /// Gets or sets listStyle to use to render the choices. @@ -70,7 +70,7 @@ public ChoiceInput([CallerFilePath] string callerPath = "", [CallerLineNumber] i /// ListStyle to use to render the choices. /// [JsonProperty("style")] - public ListStyle Style { get; set; } = ListStyle.Auto; + public EnumExpression Style { get; set; } = ListStyle.Auto; /// /// Gets or sets defaultLocale. @@ -79,7 +79,7 @@ public ChoiceInput([CallerFilePath] string callerPath = "", [CallerLineNumber] i /// DefaultLocale. /// [JsonProperty("defaultLocale")] - public string DefaultLocale { get; set; } = null; + public StringExpression DefaultLocale { get; set; } /// /// Gets or sets control the format of the response (value or the index of the choice). @@ -88,7 +88,7 @@ public ChoiceInput([CallerFilePath] string callerPath = "", [CallerLineNumber] i /// Control the format of the response (value or the index of the choice). /// [JsonProperty("outputFormat")] - public ChoiceOutputFormat OutputFormat { get; set; } = ChoiceOutputFormat.Value; + public EnumExpression OutputFormat { get; set; } = ChoiceOutputFormat.Value; /// /// Gets or sets choiceOptions controls display options for customizing language. @@ -97,7 +97,7 @@ public ChoiceInput([CallerFilePath] string callerPath = "", [CallerLineNumber] i /// ChoiceOptions controls display options for customizing language. /// [JsonProperty("choiceOptions")] - public ChoiceFactoryOptions ChoiceOptions { get; set; } = null; + public ObjectExpression ChoiceOptions { get; set; } /// /// Gets or sets customize how to use the choices to recognize the response from the user. @@ -106,7 +106,7 @@ public ChoiceInput([CallerFilePath] string callerPath = "", [CallerLineNumber] i /// Customize how to use the choices to recognize the response from the user. /// [JsonProperty("recognizerOptions")] - public FindChoicesOptions RecognizerOptions { get; set; } = null; + public ObjectExpression RecognizerOptions { get; set; } = null; public override Task ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -125,12 +125,18 @@ protected override object OnInitializeOptions(DialogContext dc, object options) var op = options as ChoiceInputOptions; if (op == null || op.Choices == null || op.Choices.Count == 0) { + var dcState = dc.GetState(); if (op == null) { op = new ChoiceInputOptions(); } - var choices = this.Choices.GetValue(dc.GetState()); + var (choices, error) = this.Choices.TryGetValue(dcState); + if (error != null) + { + throw new Exception(error); + } + op.Choices = choices; } @@ -139,15 +145,17 @@ protected override object OnInitializeOptions(DialogContext dc, object options) protected override Task OnRecognizeInput(DialogContext dc) { - var input = dc.GetState().GetValue(VALUE_PROPERTY); - var options = dc.GetState().GetValue(ThisPath.OPTIONS); + var dcState = dc.GetState(); + + var input = dcState.GetValue(VALUE_PROPERTY); + var options = dcState.GetValue(ThisPath.OPTIONS); var choices = options.Choices; var result = new PromptRecognizerResult(); if (dc.Context.Activity.Type == ActivityTypes.Message) { - var opt = this.RecognizerOptions ?? new FindChoicesOptions(); + var opt = this.RecognizerOptions?.GetValue(dcState) ?? new FindChoicesOptions(); opt.Locale = GetCulture(dc); var results = ChoiceRecognizers.RecognizeChoices(input.ToString(), choices, opt); if (results == null || results.Count == 0) @@ -156,14 +164,14 @@ protected override Task OnRecognizeInput(DialogContext dc) } var foundChoice = results[0].Resolution; - switch (this.OutputFormat) + switch (this.OutputFormat.GetValue(dcState)) { case ChoiceOutputFormat.Value: default: - dc.GetState().SetValue(VALUE_PROPERTY, foundChoice.Value); + dcState.SetValue(VALUE_PROPERTY, foundChoice.Value); break; case ChoiceOutputFormat.Index: - dc.GetState().SetValue(VALUE_PROPERTY, foundChoice.Index); + dcState.SetValue(VALUE_PROPERTY, foundChoice.Index); break; } } @@ -173,27 +181,34 @@ protected override Task OnRecognizeInput(DialogContext dc) protected override async Task OnRenderPrompt(DialogContext dc, InputState state) { + var dcState = dc.GetState(); var locale = GetCulture(dc); var prompt = await base.OnRenderPrompt(dc, state); var channelId = dc.Context.Activity.ChannelId; var choicePrompt = new ChoicePrompt(this.Id); - var choiceOptions = this.ChoiceOptions ?? ChoiceInput.DefaultChoiceOptions[locale]; + var choiceOptions = this.ChoiceOptions?.GetValue(dcState) ?? ChoiceInput.DefaultChoiceOptions[locale]; - var choices = this.Choices.GetValue(dc.GetState()); + var (choices, error) = this.Choices.TryGetValue(dcState); + if (error != null) + { + throw new Exception(error); + } - return this.AppendChoices(prompt.AsMessageActivity(), channelId, choices, this.Style, choiceOptions); + return this.AppendChoices(prompt.AsMessageActivity(), channelId, choices, this.Style.GetValue(dcState), choiceOptions); } private string GetCulture(DialogContext dc) { + var dcState = dc.GetState(); + if (!string.IsNullOrWhiteSpace(dc.Context.Activity.Locale)) { return dc.Context.Activity.Locale; } - if (!string.IsNullOrWhiteSpace(this.DefaultLocale)) + if (this.DefaultLocale != null) { - return this.DefaultLocale; + return this.DefaultLocale.GetValue(dcState); } return English; diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ChoiceSet.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ChoiceSet.cs index f4e896705f..261aaa6a27 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ChoiceSet.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ChoiceSet.cs @@ -1,69 +1,60 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Collections.Generic; using Microsoft.Bot.Builder.Dialogs.Choices; -using Microsoft.Bot.Builder.Dialogs.Declarative; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -namespace Microsoft.Bot.Builder.Dialogs.Adaptive +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input { /// - /// Defines Choices Property as either collection of Choices, array of strings or string which is an expression to one of thoses. + /// Defines ChoiceSet collection. /// - public class ChoiceSet : ExpressionProperty> + [JsonConverter(typeof(ChoiceSetConverter))] + public class ChoiceSet : List { public ChoiceSet() { } - public ChoiceSet(string expression) - : base(expression) - { - } - - public ChoiceSet(List choices) - : base(choices) - { - } - - public ChoiceSet(object choices) + public ChoiceSet(IEnumerable choices) : base(choices) { } - protected override List ConvertObject(object result) + public ChoiceSet(object obj) { // support string[] => choice[] - if (result is IEnumerable strings) + if (obj is IEnumerable strings) { - return strings.Select(s => new Choice(s)).ToList(); + foreach (var str in strings) + { + this.Add(new Choice(str)); + } } // support JArray to => choice - if (result is JArray array) + if (obj is JArray array) { - var choices = new List(); if (array.HasValues) { foreach (var element in array) { if (element is JValue jval) { - choices.Add(new Choice(element.ToString())); + this.Add(new Choice(element.ToString())); } else if (element is JObject jobj) { - choices.Add(jobj.ToObject()); + this.Add(jobj.ToObject()); } } } - - return choices; } - - return JArray.FromObject(result).ToObject>(); } + + public static implicit operator ChoiceSet(bool value) => new ChoiceSet(value); + + public static implicit operator ChoiceSet(string value) => new ChoiceSet(value); + + public static implicit operator ChoiceSet(JToken value) => new ChoiceSet(value); } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ConfirmInput.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ConfirmInput.cs index 995b0dd7ed..465e1000e0 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ConfirmInput.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/ConfirmInput.cs @@ -6,6 +6,7 @@ using System.Runtime.CompilerServices; using System.Threading.Tasks; using Microsoft.Bot.Builder.Dialogs.Choices; +using Microsoft.Bot.Builder.Dialogs.Declarative; using Microsoft.Bot.Expressions; using Microsoft.Bot.Schema; using Microsoft.Recognizers.Text.Choice; @@ -40,23 +41,24 @@ public ConfirmInput([CallerFilePath] string callerPath = "", [CallerLineNumber] } [JsonProperty("defaultLocale")] - public string DefaultLocale { get; set; } = null; + public StringExpression DefaultLocale { get; set; } [JsonProperty("style")] - public ListStyle Style { get; set; } = ListStyle.Auto; + public EnumExpression Style { get; set; } = ListStyle.Auto; [JsonProperty("choiceOptions")] - public ChoiceFactoryOptions ChoiceOptions { get; set; } = null; + public ObjectExpression ChoiceOptions { get; set; } [JsonProperty("confirmChoices")] - public List ConfirmChoices { get; set; } = null; + public ArrayExpression ConfirmChoices { get; set; } [JsonProperty("outputFormat")] - public string OutputFormat { get; set; } + public StringExpression OutputFormat { get; set; } protected override Task OnRecognizeInput(DialogContext dc) { - var input = dc.GetState().GetValue(VALUE_PROPERTY); + var dcState = dc.GetState(); + var input = dcState.GetValue(VALUE_PROPERTY); if (dc.Context.Activity.Type == ActivityTypes.Message) { // Recognize utterance @@ -67,18 +69,17 @@ protected override Task OnRecognizeInput(DialogContext dc) var first = results[0]; if (bool.TryParse(first.Resolution["value"].ToString(), out var value)) { - dc.GetState().SetValue(VALUE_PROPERTY, value); - if (!string.IsNullOrEmpty(OutputFormat)) + dcState.SetValue(VALUE_PROPERTY, value); + if (OutputFormat != null) { - var outputExpression = new ExpressionEngine().Parse(OutputFormat); - var (outputValue, error) = outputExpression.TryEvaluate(dc.GetState()); + var (outputValue, error) = OutputFormat.TryGetValue(dcState); if (error == null) { - dc.GetState().SetValue(VALUE_PROPERTY, outputValue); + dcState.SetValue(VALUE_PROPERTY, outputValue); } else { - throw new Exception($"OutputFormat Expression evaluation resulted in an error. Expression: {outputExpression.ToString()}. Error: {error}"); + throw new Exception($"OutputFormat Expression evaluation resulted in an error. Expression: {OutputFormat.ToString()}. Error: {error}"); } } @@ -93,18 +94,18 @@ protected override Task OnRecognizeInput(DialogContext dc) { // First check whether the prompt was sent to the user with numbers - if it was we should recognize numbers var defaults = ChoiceDefaults[culture]; - var choiceOptions = ChoiceOptions ?? defaults.Item3; + var choiceOptions = ChoiceOptions?.GetValue(dcState) ?? defaults.Item3; // This logic reflects the fact that IncludeNumbers is nullable and True is the default set in Inline style if (!choiceOptions.IncludeNumbers.HasValue || choiceOptions.IncludeNumbers.Value) { // The text may be a number in which case we will interpret that as a choice. - var confirmChoices = ConfirmChoices ?? new List() { defaults.Item1, defaults.Item2 }; + var confirmChoices = ConfirmChoices?.GetValue(dcState) ?? new List() { defaults.Item1, defaults.Item2 }; var secondAttemptResults = ChoiceRecognizers.RecognizeChoices(input.ToString(), confirmChoices); if (secondAttemptResults.Count > 0) { input = secondAttemptResults[0].Resolution.Index == 0; - dc.GetState().SetValue(VALUE_PROPERTY, input); + dcState.SetValue(VALUE_PROPERTY, input); } else { @@ -120,15 +121,16 @@ protected override Task OnRecognizeInput(DialogContext dc) protected override async Task OnRenderPrompt(DialogContext dc, InputState state) { // Format prompt to send + var dcState = dc.GetState(); var channelId = dc.Context.Activity.ChannelId; var culture = GetCulture(dc); var defaults = ChoiceDefaults[culture]; - var choiceOptions = ChoiceOptions ?? defaults.Item3; - var confirmChoices = ConfirmChoices ?? new List() { defaults.Item1, defaults.Item2 }; + var choiceOptions = ChoiceOptions?.GetValue(dcState) ?? defaults.Item3; + var confirmChoices = ConfirmChoices?.GetValue(dcState) ?? new List() { defaults.Item1, defaults.Item2 }; var prompt = await base.OnRenderPrompt(dc, state); - - return this.AppendChoices(prompt.AsMessageActivity(), channelId, confirmChoices, this.Style, choiceOptions); + var (style, error) = this.Style.TryGetValue(dcState); + return this.AppendChoices(prompt.AsMessageActivity(), channelId, confirmChoices, style, choiceOptions); } private string GetCulture(DialogContext dc) @@ -138,9 +140,10 @@ private string GetCulture(DialogContext dc) return dc.Context.Activity.Locale; } - if (!string.IsNullOrEmpty(this.DefaultLocale)) + if (this.DefaultLocale != null) { - return this.DefaultLocale; + var dcState = dc.GetState(); + return this.DefaultLocale.GetValue(dcState); } return English; diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/DateTimeInput.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/DateTimeInput.cs index de88153253..0affded324 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/DateTimeInput.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/DateTimeInput.cs @@ -23,17 +23,18 @@ public DateTimeInput([CallerFilePath] string callerPath = "", [CallerLineNumber] } [JsonProperty("defaultLocale")] - public string DefaultLocale { get; set; } = null; + public StringExpression DefaultLocale { get; set; } = null; [JsonProperty("outputFormat")] - public string OutputFormat { get; set; } + public StringExpression OutputFormat { get; set; } protected override Task OnRecognizeInput(DialogContext dc) { - var input = dc.GetState().GetValue(VALUE_PROPERTY); - + var dcState = dc.GetState(); + var input = dcState.GetValue(VALUE_PROPERTY); var culture = GetCulture(dc); - var results = DateTimeRecognizer.RecognizeDateTime(input.ToString(), culture); + var refTime = dc.Context.Activity.LocalTimestamp?.LocalDateTime; + var results = DateTimeRecognizer.RecognizeDateTime(input.ToString(), culture, refTime: refTime); if (results.Count > 0) { // Return list of resolutions from first match @@ -44,18 +45,18 @@ protected override Task OnRecognizeInput(DialogContext dc) result.Add(ReadResolution(value)); } - dc.GetState().SetValue(VALUE_PROPERTY, result); - if (!string.IsNullOrEmpty(OutputFormat)) + dcState.SetValue(VALUE_PROPERTY, result); + + if (OutputFormat != null) { - var outputExpression = new ExpressionEngine().Parse(OutputFormat); - var (outputValue, error) = outputExpression.TryEvaluate(dc.GetState()); + var (outputValue, error) = this.OutputFormat.TryGetValue(dcState); if (error == null) { - dc.GetState().SetValue(VALUE_PROPERTY, outputValue); + dcState.SetValue(VALUE_PROPERTY, outputValue); } else { - throw new Exception($"OutputFormat Expression evaluation resulted in an error. Expression: {outputExpression.ToString()}. Error: {error}"); + throw new Exception($"OutputFormat Expression evaluation resulted in an error. Expression: {this.OutputFormat}. Error: {error}"); } } } @@ -101,9 +102,10 @@ private string GetCulture(DialogContext dc) return dc.Context.Activity.Locale; } - if (!string.IsNullOrEmpty(this.DefaultLocale)) + if (this.DefaultLocale != null) { - return this.DefaultLocale; + var dcState = dc.GetState(); + return this.DefaultLocale.GetValue(dcState); } return English; diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/InputDialog.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/InputDialog.cs index 600feef796..aa5b2a7a1d 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/InputDialog.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/InputDialog.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -21,9 +22,6 @@ public abstract class InputDialog : Dialog protected const string VALUE_PROPERTY = "this.value"; #pragma warning restore SA1310 // Field should not contain underscore. - private Expression allowInterruptions; - private Expression disabled; - /// /// Gets or sets a value indicating whether the input should always prompt the user regardless of there being a value or not. /// @@ -31,7 +29,7 @@ public abstract class InputDialog : Dialog /// A value indicating whether the input should always prompt the user regardless of there being a value or not. /// [JsonProperty("alwaysPrompt")] - public bool AlwaysPrompt { get; set; } = false; + public BoolExpression AlwaysPrompt { get; set; } /// /// Gets or sets intteruption policy. @@ -40,14 +38,10 @@ public abstract class InputDialog : Dialog /// "true". /// /// - /// Intteruption policy. + /// Intteruption policy. Default is True. /// [JsonProperty("allowInterruptions")] - public string AllowInterruptions - { - get { return allowInterruptions?.ToString(); } - set { allowInterruptions = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression AllowInterruptions { get; set; } /// /// Gets or sets an optional expression which if is true will disable this action. @@ -56,23 +50,19 @@ public string AllowInterruptions /// "user.age > 18". /// /// - /// A boolean expression. + /// A boolean expression. Default is false. /// [JsonProperty("disabled")] - public string Disabled - { - get { return disabled?.ToString(); } - set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public BoolExpression Disabled { get; set; } /// - /// Gets or sets the value expression which the input will be bound to. + /// Gets or sets the memory property path which the value will be bound to. /// /// - /// The value expression which the input will be bound to. + /// The property path to the value that the input dialog will be bound to. /// [JsonProperty("property")] - public string Property { get; set; } + public StringExpression Property { get; set; } /// /// Gets or sets a value expression which can be used to intialize the input prompt. @@ -85,7 +75,7 @@ public string Disabled /// A value expression which can be used to intialize the input prompt. /// [JsonProperty("value")] - public string Value { get; set; } + public ValueExpression Value { get; set; } /// /// Gets or sets the activity to send to the user. @@ -133,13 +123,13 @@ public string Disabled public List Validations { get; set; } = new List(); /// - /// Gets or sets maximum number of times to ask the user for this value before the dilog gives up. + /// Gets or sets maximum number of times to ask the user for this value before the dialog gives up. /// /// /// Maximum number of times to ask the user for this value before the dilog gives up. /// [JsonProperty("maxTurnCount")] - public int? MaxTurnCount { get; set; } + public IntExpression MaxTurnCount { get; set; } /// /// Gets or sets the default value for the input dialog when MaxTurnCount is exceeded. @@ -148,7 +138,7 @@ public string Disabled /// The default value for the input dialog when MaxTurnCount is exceeded. /// [JsonProperty("defaultValue")] - public string DefaultValue { get; set; } + public ValueExpression DefaultValue { get; set; } public override async Task BeginDialogAsync(DialogContext dc, object options, CancellationToken cancellationToken = default(CancellationToken)) { @@ -162,28 +152,33 @@ public string Disabled throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState) == true) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } var op = OnInitializeOptions(dc, options); - dc.GetState().SetValue(ThisPath.OPTIONS, op); - dc.GetState().SetValue(TURN_COUNT_PROPERTY, 0); + dcState.SetValue(ThisPath.OPTIONS, op); + dcState.SetValue(TURN_COUNT_PROPERTY, 0); + + var alwaysPrompt = this.AlwaysPrompt?.GetValue(dcState) ?? false; // If AlwaysPrompt is set to true, then clear Property value for turn 0. - if (!string.IsNullOrEmpty(this.Property) && this.AlwaysPrompt) + var property = this.Property?.GetValue(dcState); + if (property != null && alwaysPrompt) { - dc.GetState().SetValue(this.Property, null); + dcState.SetValue(property, null); } - var state = this.AlwaysPrompt ? InputState.Missing : await this.RecognizeInput(dc, 0); + var state = alwaysPrompt ? InputState.Missing : await this.RecognizeInput(dc, 0); if (state == InputState.Valid) { - var input = dc.GetState().GetValue(VALUE_PROPERTY); + var input = dcState.GetValue(VALUE_PROPERTY); // set property - dc.GetState().SetValue(this.Property, input); + dcState.SetValue(property, input); // return as result too return await dc.EndDialogAsync(input); @@ -193,7 +188,7 @@ public string Disabled // turnCount should increase here, because you want when nextTurn comes in // We will set the turn count to 1 so the input will not pick from "dialog.value" // and instead go with "turn.activity.text" - dc.GetState().SetValue(TURN_COUNT_PROPERTY, 1); + dcState.SetValue(TURN_COUNT_PROPERTY, 1); return await this.PromptUser(dc, state); } } @@ -206,43 +201,45 @@ public string Disabled return Dialog.EndOfTurn; } - var interrupted = dc.GetState().GetValue(TurnPath.INTERRUPTED, () => false); - var turnCount = dc.GetState().GetValue(TURN_COUNT_PROPERTY, () => 0); + var dcState = dc.GetState(); + + var interrupted = dcState.GetValue(TurnPath.INTERRUPTED, () => false); + var turnCount = dcState.GetValue(TURN_COUNT_PROPERTY, () => 0); // Perform base recognition var state = await this.RecognizeInput(dc, interrupted ? 0 : turnCount); if (state == InputState.Valid) { - var input = dc.GetState().GetValue(VALUE_PROPERTY); + var input = dcState.GetValue(VALUE_PROPERTY); // set output property - if (!string.IsNullOrEmpty(this.Property)) + if (this.Property != null) { - dc.GetState().SetValue(this.Property, input); + dcState.SetValue(this.Property.GetValue(dcState), input); } return await dc.EndDialogAsync(input).ConfigureAwait(false); } - else if (this.MaxTurnCount == null || turnCount < this.MaxTurnCount) + else if (this.MaxTurnCount == null || turnCount < this.MaxTurnCount.GetValue(dcState)) { // increase the turnCount as last step - dc.GetState().SetValue(TURN_COUNT_PROPERTY, turnCount + 1); + dcState.SetValue(TURN_COUNT_PROPERTY, turnCount + 1); return await this.PromptUser(dc, state).ConfigureAwait(false); } else { if (this.DefaultValue != null) { - var (value, error) = new ExpressionEngine().Parse(this.DefaultValue).TryEvaluate(dc.GetState()); + var (value, error) = this.DefaultValue.TryGetValue(dcState); if (this.DefaultValueResponse != null) { - var response = await this.DefaultValueResponse.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false); + var response = await this.DefaultValueResponse.BindToData(dc.Context, dcState).ConfigureAwait(false); await dc.Context.SendActivityAsync(response).ConfigureAwait(false); } // set output property - dc.GetState().SetValue(this.Property, value); + dcState.SetValue(this.Property.GetValue(dcState), value); return await dc.EndDialogAsync(value).ConfigureAwait(false); } @@ -262,15 +259,17 @@ protected override async Task OnPreBubbleEventAsync(DialogContext dc, Dial { if (e.Name == DialogEvents.ActivityReceived && dc.Context.Activity.Type == ActivityTypes.Message) { + var dcState = dc.GetState(); + // Ask parent to perform recognition await dc.Parent.EmitEventAsync(AdaptiveEvents.RecognizeUtterance, value: dc.Context.Activity, bubble: false, cancellationToken: cancellationToken).ConfigureAwait(false); // Should we allow interruptions var canInterrupt = true; - if (allowInterruptions != null) + if (this.AllowInterruptions != null) { - var (value, error) = allowInterruptions.TryEvaluate(dc.GetState()); - canInterrupt = error == null && value != null && (bool)value; + var (allowInterruptions, error) = this.AllowInterruptions.TryGetValue(dcState); + canInterrupt = error == null && allowInterruptions; } // Stop bubbling if interruptions ar NOT allowed @@ -349,16 +348,18 @@ protected virtual object OnInitializeOptions(DialogContext dc, object options) protected virtual async Task OnRenderPrompt(DialogContext dc, InputState state) { + var dcState = dc.GetState(); + switch (state) { case InputState.Unrecognized: if (this.UnrecognizedPrompt != null) { - return await this.UnrecognizedPrompt.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false); + return await this.UnrecognizedPrompt.BindToData(dc.Context, dcState).ConfigureAwait(false); } else if (this.InvalidPrompt != null) { - return await this.InvalidPrompt.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false); + return await this.InvalidPrompt.BindToData(dc.Context, dcState).ConfigureAwait(false); } break; @@ -366,47 +367,50 @@ protected virtual async Task OnRenderPrompt(DialogContext dc, InputSt case InputState.Invalid: if (this.InvalidPrompt != null) { - return await this.InvalidPrompt.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false); + return await this.InvalidPrompt.BindToData(dc.Context, dcState).ConfigureAwait(false); } else if (this.UnrecognizedPrompt != null) { - return await this.UnrecognizedPrompt.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false); + return await this.UnrecognizedPrompt.BindToData(dc.Context, dcState).ConfigureAwait(false); } break; } - return await this.Prompt.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false); + return await this.Prompt.BindToData(dc.Context, dcState).ConfigureAwait(false); } private async Task RecognizeInput(DialogContext dc, int turnCount) { dynamic input = null; + var dcState = dc.GetState(); + // Use Property expression for input first - if (!string.IsNullOrEmpty(this.Property)) + if (this.Property != null) { - dc.GetState().TryGetValue(this.Property, out input); + var property = this.Property.GetValue(dcState); + dcState.TryGetValue(property, out input); // Clear property to avoid it being stuck on the next turn. It will get written // back if the value passes validations. - dc.GetState().SetValue(this.Property, null); + dcState.SetValue(property, null); } // Use Value expression for input second - if (input == null && !string.IsNullOrEmpty(this.Value)) + if (input == null && this.Value != null) { - var (value, valueError) = new ExpressionEngine().Parse(this.Value).TryEvaluate(dc.GetState()); + var (value, valueError) = this.Value.TryGetValue(dcState); if (valueError != null) - { + { throw new Exception($"In InputDialog, this.Value expression evaluation resulted in an error. Expression: {this.Value}. Error: {valueError}"); } - + input = value; } // Fallback to using activity - bool activityProcessed = dc.GetState().GetBoolValue(TurnPath.ACTIVITYPROCESSED); + bool activityProcessed = dcState.GetBoolValue(TurnPath.ACTIVITYPROCESSED); if (!activityProcessed && input == null && turnCount > 0) { if (this.GetType().Name == nameof(AttachmentInput)) @@ -420,7 +424,7 @@ private async Task RecognizeInput(DialogContext dc, int turnCount) } // Update "this.value" and perform additional recognition and validations - dc.GetState().SetValue(VALUE_PROPERTY, input); + dcState.SetValue(VALUE_PROPERTY, input); if (input != null) { var state = await this.OnRecognizeInput(dc).ConfigureAwait(false); @@ -428,15 +432,15 @@ private async Task RecognizeInput(DialogContext dc, int turnCount) { foreach (var validation in this.Validations) { - var exp = new ExpressionEngine().Parse(validation); - var (value, error) = exp.TryEvaluate(dc.GetState()); + var exp = new ExpressionEngine().Parse(validation.TrimStart('=')); + var (value, error) = exp.TryEvaluate(dcState); if (value == null || (value is bool && (bool)value == false)) { return InputState.Invalid; } } - - dc.GetState().SetValue(TurnPath.ACTIVITYPROCESSED, true); + + dcState.SetValue(TurnPath.ACTIVITYPROCESSED, true); return InputState.Valid; } else diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/NumberInput.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/NumberInput.cs index c584c2836b..3cc0855dd5 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/NumberInput.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/NumberInput.cs @@ -23,14 +23,15 @@ public NumberInput([CallerFilePath] string callerPath = "", [CallerLineNumber] i } [JsonProperty("defaultLocale")] - public string DefaultLocale { get; set; } = null; + public StringExpression DefaultLocale { get; set; } = null; [JsonProperty("outputFormat")] - public string OutputFormat { get; set; } + public NumberExpression OutputFormat { get; set; } protected override Task OnRecognizeInput(DialogContext dc) { - var input = dc.GetState().GetValue(VALUE_PROPERTY); + var dcState = dc.GetState(); + var input = dcState.GetValue(VALUE_PROPERTY); var culture = GetCulture(dc); var results = NumberRecognizer.RecognizeNumber(input.ToString(), culture); @@ -60,22 +61,21 @@ protected override Task OnRecognizeInput(DialogContext dc) return Task.FromResult(InputState.Unrecognized); } - dc.GetState().SetValue(VALUE_PROPERTY, input); + dcState.SetValue(VALUE_PROPERTY, input); - if (!string.IsNullOrEmpty(OutputFormat)) + if (OutputFormat != null) { - var outputExpression = new ExpressionEngine().Parse(OutputFormat); - var (outputValue, error) = outputExpression.TryEvaluate(dc.GetState()); + var (outputValue, error) = this.OutputFormat.TryGetValue(dcState); if (error == null) { - dc.GetState().SetValue(VALUE_PROPERTY, outputValue); + dcState.SetValue(VALUE_PROPERTY, outputValue); } else { - throw new Exception($"In TextInput, OutputFormat Expression evaluation resulted in an error. Expression: {outputExpression.ToString()}. Error: {error}"); + throw new Exception($"In TextInput, OutputFormat Expression evaluation resulted in an error. Expression: {this.OutputFormat}. Error: {error}"); } } - + return Task.FromResult(InputState.Valid); } @@ -86,9 +86,11 @@ private string GetCulture(DialogContext dc) return dc.Context.Activity.Locale; } - if (!string.IsNullOrEmpty(this.DefaultLocale)) + if (this.DefaultLocale != null) { - return this.DefaultLocale; + var dcState = dc.GetState(); + + return this.DefaultLocale.GetValue(dcState); } return English; diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/OAuthInput.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/OAuthInput.cs index 2ca1d36a32..cb0c8a98be 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/OAuthInput.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/OAuthInput.cs @@ -34,21 +34,21 @@ public class OAuthInput : InputDialog /// /// The name of the OAuth connection. [JsonProperty("connectionName")] - public string ConnectionName { get; set; } + public StringExpression ConnectionName { get; set; } /// /// Gets or sets the title of the sign-in card. /// /// The title of the sign-in card. [JsonProperty("title")] - public string Title { get; set; } + public StringExpression Title { get; set; } /// /// Gets or sets any additional text to include in the sign-in card. /// /// Any additional text to include in the sign-in card. [JsonProperty("text")] - public string Text { get; set; } + public StringExpression Text { get; set; } /// /// Gets or sets the number of milliseconds the prompt waits for the user to authenticate. @@ -56,7 +56,7 @@ public class OAuthInput : InputDialog /// /// The number of milliseconds the prompt waits for the user to authenticate. [JsonProperty("timeout")] - public int Timeout { get; set; } = 900000; + public IntExpression Timeout { get; set; } = 900000; /// /// Called when a prompt dialog is pushed onto the dialog stack and is being activated. @@ -80,7 +80,9 @@ public class OAuthInput : InputDialog throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } - if (this.Disabled != null && (bool)new ExpressionEngine().Parse(this.Disabled).TryEvaluate(dc.GetState()).value == true) + var dcState = dc.GetState(); + + if (this.Disabled != null && this.Disabled.GetValue(dcState)) { return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } @@ -105,13 +107,15 @@ public class OAuthInput : InputDialog } var op = OnInitializeOptions(dc, options); - dc.GetState().SetValue(ThisPath.OPTIONS, op); - dc.GetState().SetValue(TURN_COUNT_PROPERTY, 0); + dcState.SetValue(ThisPath.OPTIONS, op); + dcState.SetValue(TURN_COUNT_PROPERTY, 0); // If AlwaysPrompt is set to true, then clear Property value for turn 0. - if (!string.IsNullOrEmpty(this.Property) && this.AlwaysPrompt) + var (alwaysPrompt, _) = this.AlwaysPrompt.TryGetValue(dcState); + + if (this.Property != null && alwaysPrompt) { - dc.GetState().SetValue(this.Property, null); + dcState.SetValue(this.Property.GetValue(dcState), null); } // Initialize state @@ -122,7 +126,7 @@ public class OAuthInput : InputDialog { AttemptCountKey, 0 }, }; - state[PersistedExpires] = DateTime.Now.AddMilliseconds(Timeout); + state[PersistedExpires] = DateTime.Now.AddMilliseconds(Timeout.GetValue(dcState)); // Attempt to get the users token if (!(dc.Context.Adapter is IUserTokenProvider adapter)) @@ -130,12 +134,12 @@ public class OAuthInput : InputDialog throw new InvalidOperationException("OAuthPrompt.Recognize(): not supported by the current adapter"); } - var output = await adapter.GetUserTokenAsync(dc.Context, ConnectionName, null, cancellationToken).ConfigureAwait(false); + var output = await adapter.GetUserTokenAsync(dc.Context, ConnectionName.GetValue(dcState), null, cancellationToken).ConfigureAwait(false); if (output != null) { if (this.Property != null) { - dc.GetState().SetValue(this.Property, output); + dcState.SetValue(this.Property.GetValue(dcState), output); } // Return token @@ -143,10 +147,10 @@ public class OAuthInput : InputDialog } else { - dc.GetState().SetValue(TURN_COUNT_PROPERTY, 1); + dcState.SetValue(TURN_COUNT_PROPERTY, 1); // Prompt user to login - await SendOAuthCardAsync(dc.Context, opt?.Prompt, cancellationToken).ConfigureAwait(false); + await SendOAuthCardAsync(dc, opt?.Prompt, cancellationToken).ConfigureAwait(false); return Dialog.EndOfTurn; } } @@ -169,11 +173,12 @@ public class OAuthInput : InputDialog throw new ArgumentNullException(nameof(dc)); } - var interrupted = dc.GetState().GetValue(TurnPath.INTERRUPTED, () => false); - var turnCount = dc.GetState().GetValue(TURN_COUNT_PROPERTY, () => 0); + var dcState = dc.GetState(); + var interrupted = dcState.GetValue(TurnPath.INTERRUPTED, () => false); + var turnCount = dcState.GetValue(TURN_COUNT_PROPERTY, () => 0); // Recognize token - var recognized = await RecognizeTokenAsync(dc.Context, cancellationToken).ConfigureAwait(false); + var recognized = await RecognizeTokenAsync(dc, cancellationToken).ConfigureAwait(false); // Check for timeout var state = dc.ActiveDialog.State; @@ -185,7 +190,7 @@ public class OAuthInput : InputDialog { if (this.Property != null) { - dc.GetState().SetValue(this.Property, null); + dcState.SetValue(this.Property.GetValue(dcState), null); } // if the token fetch request times out, complete the prompt with no result. @@ -212,33 +217,33 @@ public class OAuthInput : InputDialog { if (this.Property != null) { - dc.GetState().SetValue(this.Property, recognized.Value); + dcState.SetValue(this.Property.GetValue(dcState), recognized.Value); } return await dc.EndDialogAsync(recognized.Value, cancellationToken).ConfigureAwait(false); } - else if (this.MaxTurnCount == null || turnCount < this.MaxTurnCount) + else if (this.MaxTurnCount == null || turnCount < this.MaxTurnCount.GetValue(dcState)) { // increase the turnCount as last step - dc.GetState().SetValue(TURN_COUNT_PROPERTY, turnCount + 1); + dcState.SetValue(TURN_COUNT_PROPERTY, turnCount + 1); var prompt = await this.OnRenderPrompt(dc, inputState).ConfigureAwait(false); await dc.Context.SendActivityAsync(prompt).ConfigureAwait(false); - await SendOAuthCardAsync(dc.Context, promptOptions?.Prompt, cancellationToken).ConfigureAwait(false); + await SendOAuthCardAsync(dc, promptOptions?.Prompt, cancellationToken).ConfigureAwait(false); return Dialog.EndOfTurn; } else { if (this.DefaultValue != null) { - var (value, error) = new ExpressionEngine().Parse(this.DefaultValue).TryEvaluate(dc.GetState()); + var (value, _) = this.DefaultValue.TryGetValue(dcState); if (this.DefaultValueResponse != null) { - var response = await this.DefaultValueResponse.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false); + var response = await this.DefaultValueResponse.BindToData(dc.Context, dcState).ConfigureAwait(false); await dc.Context.SendActivityAsync(response).ConfigureAwait(false); } // set output property - dc.GetState().SetValue(this.Property, value); + dcState.SetValue(this.Property.GetValue(dcState), value); return await dc.EndDialogAsync(value).ConfigureAwait(false); } } @@ -250,38 +255,41 @@ public class OAuthInput : InputDialog /// /// Attempts to get the user's token. /// - /// Context for the current turn of conversation with the user. + /// DialogContext for the current turn of conversation with the user. /// A cancellation token that can be used by other objects /// or threads to receive notice of cancellation. /// A task that represents the work queued to execute. /// If the task is successful and user already has a token or the user successfully signs in, /// the result contains the user's token. - public async Task GetUserTokenAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) + public async Task GetUserTokenAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { - if (!(turnContext.Adapter is IUserTokenProvider adapter)) + if (!(dc.Context.Adapter is IUserTokenProvider adapter)) { throw new InvalidOperationException("OAuthPrompt.GetUserToken(): not supported by the current adapter"); } - return await adapter.GetUserTokenAsync(turnContext, ConnectionName, null, cancellationToken).ConfigureAwait(false); + var dcState = dc.GetState(); + return await adapter.GetUserTokenAsync(dc.Context, ConnectionName.GetValue(dcState), null, cancellationToken).ConfigureAwait(false); } /// /// Signs out the user. /// - /// Context for the current turn of conversation with the user. + /// DialogContext for the current turn of conversation with the user. /// A cancellation token that can be used by other objects /// or threads to receive notice of cancellation. /// A task that represents the work queued to execute. - public async Task SignOutUserAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) + public async Task SignOutUserAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { - if (!(turnContext.Adapter is IUserTokenProvider adapter)) + if (!(dc.Context.Adapter is IUserTokenProvider adapter)) { throw new InvalidOperationException("OAuthPrompt.SignOutUser(): not supported by the current adapter"); } + var dcState = dc.GetState(); + // Sign out user - await adapter.SignOutUserAsync(turnContext, ConnectionName, turnContext.Activity?.From?.Id, cancellationToken).ConfigureAwait(false); + await adapter.SignOutUserAsync(dc.Context, ConnectionName.GetValue(dcState), dc.Context.Activity?.From?.Id, cancellationToken).ConfigureAwait(false); } protected override Task OnRecognizeInput(DialogContext dc) @@ -289,15 +297,17 @@ protected override Task OnRecognizeInput(DialogContext dc) throw new NotImplementedException(); } - private async Task SendOAuthCardAsync(ITurnContext turnContext, IMessageActivity prompt, CancellationToken cancellationToken = default(CancellationToken)) + private async Task SendOAuthCardAsync(DialogContext dc, IMessageActivity prompt, CancellationToken cancellationToken = default(CancellationToken)) { - BotAssert.ContextNotNull(turnContext); + var turnContext = dc.Context; if (!(turnContext.Adapter is IUserTokenProvider adapter)) { throw new InvalidOperationException("OAuthPrompt.Prompt(): not supported by the current adapter"); } + var dcState = dc.GetState(); + // Ensure prompt initialized if (prompt == null) { @@ -314,18 +324,18 @@ protected override Task OnRecognizeInput(DialogContext dc) { if (!prompt.Attachments.Any(a => a.Content is SigninCard)) { - var link = await adapter.GetOauthSignInLinkAsync(turnContext, ConnectionName, cancellationToken).ConfigureAwait(false); + var link = await adapter.GetOauthSignInLinkAsync(turnContext, ConnectionName?.GetValue(dcState), cancellationToken).ConfigureAwait(false); prompt.Attachments.Add(new Attachment { ContentType = SigninCard.ContentType, Content = new SigninCard { - Text = Text, + Text = Text?.GetValue(dcState), Buttons = new[] { new CardAction { - Title = Title, + Title = Title?.GetValue(dcState), Value = link, Type = ActionTypes.Signin, }, @@ -341,14 +351,14 @@ protected override Task OnRecognizeInput(DialogContext dc) ContentType = OAuthCard.ContentType, Content = new OAuthCard { - Text = Text, - ConnectionName = ConnectionName, + Text = Text?.GetValue(dcState), + ConnectionName = ConnectionName?.GetValue(dcState), Buttons = new[] { new CardAction { - Title = Title, - Text = Text, + Title = Title?.GetValue(dcState), + Text = Text?.GetValue(dcState), Type = ActionTypes.Signin, }, }, @@ -365,22 +375,24 @@ protected override Task OnRecognizeInput(DialogContext dc) await turnContext.SendActivityAsync(prompt, cancellationToken).ConfigureAwait(false); } - private async Task> RecognizeTokenAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) + private async Task> RecognizeTokenAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { + var dcState = dc.GetState(); + var result = new PromptRecognizerResult(); - if (IsTokenResponseEvent(turnContext)) + if (IsTokenResponseEvent(dc.Context)) { - var tokenResponseObject = turnContext.Activity.Value as JObject; + var tokenResponseObject = dc.Context.Activity.Value as JObject; var token = tokenResponseObject?.ToObject(); result.Succeeded = true; result.Value = token; } - else if (IsTeamsVerificationInvoke(turnContext)) + else if (IsTeamsVerificationInvoke(dc.Context)) { - var magicCodeObject = turnContext.Activity.Value as JObject; + var magicCodeObject = dc.Context.Activity.Value as JObject; var magicCode = magicCodeObject.GetValue("state")?.ToString(); - if (!(turnContext.Adapter is IUserTokenProvider adapter)) + if (!(dc.Context.Adapter is IUserTokenProvider adapter)) { throw new InvalidOperationException("OAuthPrompt.Recognize(): not supported by the current adapter"); } @@ -394,36 +406,36 @@ protected override Task OnRecognizeInput(DialogContext dc) // progress) retry in that case. try { - var token = await adapter.GetUserTokenAsync(turnContext, ConnectionName, magicCode, cancellationToken).ConfigureAwait(false); + var token = await adapter.GetUserTokenAsync(dc.Context, ConnectionName.GetValue(dcState), magicCode, cancellationToken).ConfigureAwait(false); if (token != null) { result.Succeeded = true; result.Value = token; - await turnContext.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse }, cancellationToken).ConfigureAwait(false); + await dc.Context.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse }, cancellationToken).ConfigureAwait(false); } else { - await turnContext.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse, Value = new InvokeResponse { Status = 404 } }, cancellationToken).ConfigureAwait(false); + await dc.Context.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse, Value = new InvokeResponse { Status = 404 } }, cancellationToken).ConfigureAwait(false); } } catch { - await turnContext.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse, Value = new InvokeResponse { Status = 500 } }, cancellationToken).ConfigureAwait(false); + await dc.Context.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse, Value = new InvokeResponse { Status = 500 } }, cancellationToken).ConfigureAwait(false); } } - else if (turnContext.Activity.Type == ActivityTypes.Message) + else if (dc.Context.Activity.Type == ActivityTypes.Message) { - var matched = _magicCodeRegex.Match(turnContext.Activity.Text); + var matched = _magicCodeRegex.Match(dc.Context.Activity.Text); if (matched.Success) { - if (!(turnContext.Adapter is IUserTokenProvider adapter)) + if (!(dc.Context.Adapter is IUserTokenProvider adapter)) { throw new InvalidOperationException("OAuthPrompt.Recognize(): not supported by the current adapter"); } - var token = await adapter.GetUserTokenAsync(turnContext, ConnectionName, matched.Value, cancellationToken).ConfigureAwait(false); + var token = await adapter.GetUserTokenAsync(dc.Context, ConnectionName.GetValue(dcState), matched.Value, cancellationToken).ConfigureAwait(false); if (token != null) { result.Succeeded = true; diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/TextInput.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/TextInput.cs index b0c63843f4..a65e39fa7c 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/TextInput.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Input/TextInput.cs @@ -23,27 +23,28 @@ public TextInput([CallerFilePath] string callerPath = "", [CallerLineNumber] int } [JsonProperty("outputFormat")] - public string OutputFormat { get; set; } + public StringExpression OutputFormat { get; set; } protected override Task OnRecognizeInput(DialogContext dc) { - var input = dc.GetState().GetValue(VALUE_PROPERTY); + var dcState = dc.GetState(); - if (!string.IsNullOrEmpty(OutputFormat)) + var input = dcState.GetValue(VALUE_PROPERTY); + + if (this.OutputFormat != null) { - var outputExpression = new ExpressionEngine().Parse(OutputFormat); - var (outputValue, error) = outputExpression.TryEvaluate(dc.GetState()); + var (outputValue, error) = this.OutputFormat.TryGetValue(dcState); if (error == null) { input = outputValue.ToString(); } else { - throw new Exception($"In TextInput, OutputFormat Expression evaluation resulted in an error. Expression: {outputExpression.ToString()}. Error: {error}"); + throw new Exception($"In TextInput, OutputFormat Expression evaluation resulted in an error. Expression: {OutputFormat.ToString()}. Error: {error}"); } } - dc.GetState().SetValue(VALUE_PROPERTY, input); + dcState.SetValue(VALUE_PROPERTY, input); return input.Length > 0 ? Task.FromResult(InputState.Valid) : Task.FromResult(InputState.Unrecognized); } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/DialogStateManager.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/DialogStateManager.cs index ecf2f5a3af..60594ea938 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/DialogStateManager.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/DialogStateManager.cs @@ -383,13 +383,7 @@ public bool Remove(string key) public bool TryGetValue(string key, out object value) { - value = default; - if (this.TryGetValue(key, out var result)) - { - value = result; - } - - return true; + return this.TryGetValue(key, out value); } public void Add(KeyValuePair item) @@ -461,12 +455,15 @@ public List TrackPaths(IEnumerable paths) public bool AnyPathChanged(uint counter, IEnumerable paths) { var found = false; - foreach (var path in paths) + if (paths != null) { - if (GetValue(PathTracker + "." + path) > counter) + foreach (var path in paths) { - found = true; - break; + if (GetValue(PathTracker + "." + path) > counter) + { + found = true; + break; + } } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ArrayExpression.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ArrayExpression.cs new file mode 100644 index 0000000000..57f5038c64 --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ArrayExpression.cs @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Collections; +using System.Collections.Generic; +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive +{ + /// + /// ArrayExpression - represents a property which is either a value of array of T or a string expression to bind to a array of T. + /// + /// type of object in the array. + /// String values are always interpreted as an expression, whether it has '=' prefix or not. + public class ArrayExpression : ExpressionProperty> + { + /// + /// Initializes a new instance of the class. + /// + public ArrayExpression() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// collection of (T). + public ArrayExpression(List value) + : base(value) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// expression which evaluates to array. + public ArrayExpression(string expression) + : base(expression) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// JToken which is either a collection of (T) or expression which evalutes to array. + public ArrayExpression(JToken value) + : base(value) + { + } + + public static implicit operator ArrayExpression(List value) => new ArrayExpression(value); + + public static implicit operator ArrayExpression(string value) => new ArrayExpression(value); + + public static implicit operator ArrayExpression(JToken value) => new ArrayExpression(value); + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/BoolExpression.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/BoolExpression.cs new file mode 100644 index 0000000000..9094a444ed --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/BoolExpression.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive +{ + /// + /// BoolExpression - represents a property which is either a boolean or a string expression which resolves to a boolean. + /// + /// String values are always interpreted as an expression, whether it has '=' prefix or not. + [JsonConverter(typeof(BoolExpressionConverter))] + public class BoolExpression : ExpressionProperty + { + /// + /// Initializes a new instance of the class. + /// + public BoolExpression() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// bool value. + public BoolExpression(bool value) + : base(value) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// expression to resolve to bool. + public BoolExpression(string expression) + : base(expression) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// expression or value to resolve to bool. + public BoolExpression(JToken value) + : base(value) + { + } + + public static implicit operator BoolExpression(bool value) => new BoolExpression(value); + + public static implicit operator BoolExpression(string value) => new BoolExpression(value); + + public static implicit operator BoolExpression(JToken value) => new BoolExpression(value); + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ArrayExpressionConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ArrayExpressionConverter.cs new file mode 100644 index 0000000000..99c390fab3 --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ArrayExpressionConverter.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Data.SqlTypes; +using Microsoft.Bot.Expressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters +{ + /// + /// Converter which allows json to be expression to object or static object. + /// + /// The type of the items of the array. + public class ArrayExpressionConverter : JsonConverter> + { + public override bool CanRead => true; + + public override ArrayExpression ReadJson(JsonReader reader, Type objectType, ArrayExpression existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.ValueType == typeof(string)) + { + return new ArrayExpression((string)reader.Value); + } + else + { + return new ArrayExpression(JToken.Load(reader)); + } + } + + public override void WriteJson(JsonWriter writer, ArrayExpression value, JsonSerializer serializer) + { + if (value.Expression != null) + { + serializer.Serialize(writer, value.ToString()); + } + else + { + serializer.Serialize(writer, value.Value); + } + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/BoolExpressionConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/BoolExpressionConverter.cs new file mode 100644 index 0000000000..b675754dbb --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/BoolExpressionConverter.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Data.SqlTypes; +using Microsoft.Bot.Expressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters +{ + /// + /// Converter which allows json to be expression to object or static object. + /// + public class BoolExpressionConverter : JsonConverter + { + public BoolExpressionConverter() + { + } + + public override bool CanRead => true; + + public override BoolExpression ReadJson(JsonReader reader, Type objectType, BoolExpression existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.ValueType == typeof(string)) + { + return new BoolExpression((string)reader.Value); + } + else + { + return new BoolExpression(JToken.Load(reader)); + } + } + + public override void WriteJson(JsonWriter writer, BoolExpression value, JsonSerializer serializer) + { + if (value.Expression != null) + { + serializer.Serialize(writer, value.ToString()); + } + else + { + serializer.Serialize(writer, value.Value); + } + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ChoiceSetConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ChoiceSetConverter.cs new file mode 100644 index 0000000000..d9ce78481b --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ChoiceSetConverter.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input +{ + /// + /// Converter for ChoiceSet - allows string or array initializers. + /// + public class ChoiceSetConverter : JsonConverter + { + public override ChoiceSet ReadJson(JsonReader reader, Type objectType, ChoiceSet existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.ValueType == typeof(string)) + { + return new ChoiceSet((string)reader.Value); + } + else + { + return new ChoiceSet(JArray.Load(reader)); + } + } + + public override void WriteJson(JsonWriter writer, ChoiceSet choiceSet, JsonSerializer serializer) + { + writer.WriteStartArray(); + foreach (var choice in choiceSet) + { + JObject.FromObject(choice).WriteTo(writer); + } + + writer.WriteEndArray(); + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/DialogExpressionConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/DialogExpressionConverter.cs new file mode 100644 index 0000000000..fbdc285aa0 --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/DialogExpressionConverter.cs @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using Microsoft.Bot.Builder.Dialogs.Debugging; +using Microsoft.Bot.Builder.Dialogs.Declarative.Converters; +using Microsoft.Bot.Builder.Dialogs.Declarative.Resolvers; +using Microsoft.Bot.Expressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters +{ + /// + /// Converter which allows json to be expression to object or static object. + /// + public class DialogExpressionConverter : JsonConverter + { + private readonly InterfaceConverter converter; + + public DialogExpressionConverter(IRefResolver refResolver, ISourceMap sourceMap, Stack paths) + { + this.converter = new InterfaceConverter(refResolver, sourceMap, paths); + } + + public override bool CanRead => true; + + public override DialogExpression ReadJson(JsonReader reader, Type objectType, DialogExpression existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.ValueType == typeof(string)) + { + var id = (string)reader.Value; + if (id.StartsWith("=")) + { + return new DialogExpression(id); + } + + try + { + return new DialogExpression((Dialog)this.converter.ReadJson(new JsonTextReader(new StringReader($"\"{id}\"")), objectType, existingValue, serializer)); + } + catch (Exception) + { + return new DialogExpression($"='{id}'"); + } + } + + return new DialogExpression((Dialog)this.converter.ReadJson(reader, objectType, existingValue, serializer)); + } + + public override void WriteJson(JsonWriter writer, DialogExpression value, JsonSerializer serializer) + { + if (value.Expression != null) + { + serializer.Serialize(writer, value.ToString()); + } + else + { + serializer.Serialize(writer, value.Value); + } + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/EnumExpressionConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/EnumExpressionConverter.cs new file mode 100644 index 0000000000..a022b5928a --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/EnumExpressionConverter.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Data.SqlTypes; +using Microsoft.Bot.Expressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters +{ + /// + /// Converter which allows json to be expression to object or static object. + /// + /// The enum type to construct. + public class EnumExpressionConverter : JsonConverter> + where T : struct + { + public EnumExpressionConverter() + { + } + + public override bool CanRead => true; + + public override EnumExpression ReadJson(JsonReader reader, Type objectType, EnumExpression existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.ValueType == typeof(string)) + { + return new EnumExpression((string)reader.Value); + } + else + { + return new EnumExpression(JToken.Load(reader)); + } + } + + public override void WriteJson(JsonWriter writer, EnumExpression value, JsonSerializer serializer) + { + if (value.Expression != null) + { + serializer.Serialize(writer, value.ToString()); + } + else + { + serializer.Serialize(writer, value.Value); + } + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ExpressionPropertyConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ExpressionPropertyConverter.cs new file mode 100644 index 0000000000..a75cf111c9 --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ExpressionPropertyConverter.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Data.SqlTypes; +using Microsoft.Bot.Expressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters +{ + /// + /// Converter which allows json to be expression to object or static object. + /// + /// The property type to construct. + public class ExpressionPropertyConverter : JsonConverter> + { + public override bool CanRead => true; + + public override ExpressionProperty ReadJson(JsonReader reader, Type objectType, ExpressionProperty existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.ValueType == typeof(string)) + { + return new ExpressionProperty((string)reader.Value); + } + else + { + return new ExpressionProperty(JToken.Load(reader)); + } + } + + public override void WriteJson(JsonWriter writer, ExpressionProperty value, JsonSerializer serializer) + { + if (value.Expression != null) + { + serializer.Serialize(writer, value.ToString()); + } + else + { + serializer.Serialize(writer, value.Value); + } + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/IntExpressionConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/IntExpressionConverter.cs new file mode 100644 index 0000000000..cd59692b7b --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/IntExpressionConverter.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters +{ + /// + /// Converter which allows json to be expression to object or static object. + /// + public class IntExpressionConverter : JsonConverter + { + public IntExpressionConverter() + { + } + + public override bool CanRead => true; + + public override IntExpression ReadJson(JsonReader reader, Type objectType, IntExpression existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.ValueType == typeof(string)) + { + return new IntExpression((string)reader.Value); + } + else + { + return new IntExpression(JToken.Load(reader)); + } + } + + public override void WriteJson(JsonWriter writer, IntExpression value, JsonSerializer serializer) + { + if (value.Expression != null) + { + serializer.Serialize(writer, value.ToString()); + } + else + { + serializer.Serialize(writer, value.Value); + } + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/NumberExpressionConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/NumberExpressionConverter.cs new file mode 100644 index 0000000000..e048e8cec5 --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/NumberExpressionConverter.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Data.SqlTypes; +using Microsoft.Bot.Expressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters +{ + /// + /// Converter which allows json to be expression to object or static object. + /// + public class NumberExpressionConverter : JsonConverter + { + public NumberExpressionConverter() + { + } + + public override bool CanRead => true; + + public override NumberExpression ReadJson(JsonReader reader, Type objectType, NumberExpression existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.ValueType == typeof(string)) + { + return new NumberExpression((string)reader.Value); + } + else + { + return new NumberExpression(JToken.Load(reader)); + } + } + + public override void WriteJson(JsonWriter writer, NumberExpression value, JsonSerializer serializer) + { + if (value.Expression != null) + { + serializer.Serialize(writer, value.ToString()); + } + else + { + serializer.Serialize(writer, value.Value); + } + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ObjectExpressionConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ObjectExpressionConverter.cs new file mode 100644 index 0000000000..80d7947de2 --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ObjectExpressionConverter.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Data.SqlTypes; +using Microsoft.Bot.Expressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters +{ + /// + /// Converter which allows json to be expression to object or static object. + /// + /// The property type to construct. + public class ObjectExpressionConverter : JsonConverter> + { + public override bool CanRead => true; + + public override ObjectExpression ReadJson(JsonReader reader, Type objectType, ObjectExpression existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.ValueType == typeof(string)) + { + return new ObjectExpression((string)reader.Value); + } + else + { + return new ObjectExpression(JToken.Load(reader)); + } + } + + public override void WriteJson(JsonWriter writer, ObjectExpression value, JsonSerializer serializer) + { + if (value.Expression != null) + { + serializer.Serialize(writer, value.ToString()); + } + else + { + serializer.Serialize(writer, value.Value); + } + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/StringExpressionConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/StringExpressionConverter.cs new file mode 100644 index 0000000000..d9a9cd8012 --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/StringExpressionConverter.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Data.SqlTypes; +using Microsoft.Bot.Expressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters +{ + /// + /// Converter which allows json to be expression to object or static object. + /// + public class StringExpressionConverter : JsonConverter + { + public StringExpressionConverter() + { + } + + public override StringExpression ReadJson(JsonReader reader, Type objectType, StringExpression existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.ValueType == typeof(string)) + { + return new StringExpression((string)reader.Value); + } + else + { + return new StringExpression(JToken.Load(reader)); + } + } + + public override void WriteJson(JsonWriter writer, StringExpression value, JsonSerializer serializer) + { + if (value.Expression != null) + { + serializer.Serialize(writer, value.ToString()); + } + else + { + serializer.Serialize(writer, value.Value); + } + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ValueExpressionConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ValueExpressionConverter.cs new file mode 100644 index 0000000000..5a6e42d8ec --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/Converters/ValueExpressionConverter.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters +{ + /// + /// Converter which allows json to be expression to object or static object. + /// + public class ValueExpressionConverter : JsonConverter + { + public ValueExpressionConverter() + { + } + + public override bool CanRead => true; + + public override ValueExpression ReadJson(JsonReader reader, Type objectType, ValueExpression existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.ValueType == typeof(string)) + { + return new ValueExpression((string)reader.Value); + } + else + { + return new ValueExpression(JToken.Load(reader)); + } + } + + public override void WriteJson(JsonWriter writer, ValueExpression value, JsonSerializer serializer) + { + if (value.Expression != null) + { + serializer.Serialize(writer, value.ToString()); + } + else + { + serializer.Serialize(writer, value.Value); + } + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/DialogExpression.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/DialogExpression.cs new file mode 100644 index 0000000000..640a43fa7f --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/DialogExpression.cs @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive +{ + /// + /// DialogExpression - represents a property which is either a Dialog or a string expression for a dialogId. + /// + /// String values are always interpreted as a string with interpolation, unless it has '=' prefix or not. The result is interpreted as a resource Id or dialogId. + public class DialogExpression : ObjectExpression + { + /// + /// Initializes a new instance of the class. + /// + public DialogExpression() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// dialog value. + public DialogExpression(Dialog value) + : base(value) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// dialogId or expression to dialogId. + public DialogExpression(string dialogIdOrExpression) + : base(dialogIdOrExpression) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// JToken which is either dialog or dialogId. + public DialogExpression(JToken value) + : base(value) + { + } + + public static implicit operator DialogExpression(Dialog value) => new DialogExpression(value); + + public static implicit operator DialogExpression(string dialogIdOrExpression) => new DialogExpression(dialogIdOrExpression); + + public static implicit operator DialogExpression(JToken value) => new DialogExpression(value); + + public override void SetValue(object value) + { + if (value is string str) + { + if (!str.StartsWith("=")) + { + // Resource Id's will be resolved to actual dialog value + // if it's not a = then we want to convert to a constant string expressions to represent a + // external dialog id resolved by dc.FindDialog() + value = $"='{str}'"; + } + } + + base.SetValue(value); + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/EnumExpression.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/EnumExpression.cs new file mode 100644 index 0000000000..e21e28ea61 --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/EnumExpression.cs @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive +{ + /// + /// EnumExpression - represents a property which is either a enum(T) or a string expression which resolves to a enum(T). + /// + /// type of enum. + /// String values are always interpreted as an enum, unless it has '=' prefix in which case it is evaluated as a expression. + public class EnumExpression : ExpressionProperty + where T : struct + { + /// + /// Initializes a new instance of the class. + /// + public EnumExpression() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// value of T. + public EnumExpression(T value) + : base(value) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// expression to resolve to an enum. + public EnumExpression(string expression) + : base(expression) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// jtoken value to resolve to an enum. + public EnumExpression(JToken value) + : base(value) + { + } + + public static implicit operator EnumExpression(T value) => new EnumExpression(value); + + public static implicit operator EnumExpression(string enumOrExpression) => new EnumExpression(enumOrExpression); + + public static implicit operator EnumExpression(JToken value) => new EnumExpression(value); + + public override void SetValue(object value) + { + if (value is string stringOrExpression) + { + // if the expression is the enum value, then use that as the value, else it is an expression. + if (Enum.TryParse(stringOrExpression.TrimStart('='), ignoreCase: true, out T val)) + { + this.Value = val; + return; + } + } + + base.SetValue(value); + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ExpressionProperty.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ExpressionProperty.cs new file mode 100644 index 0000000000..098156b38d --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ExpressionProperty.cs @@ -0,0 +1,136 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Text; +using Microsoft.Bot.Builder.LanguageGeneration; +using Microsoft.Bot.Expressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive +{ + /// + /// Base class which defines a Expression or value for a property. + /// + /// type of object the expression should evaluate to. + public class ExpressionProperty + { + public ExpressionProperty() + { + } + + public ExpressionProperty(object value) + { + SetValue(value); + } + + public T Value { get; set; } = default(T); + + public Expression Expression { get; set; } + + public new string ToString() + { + if (this.Expression != null) + { + return $"={this.Expression}"; + } + + return this.Value?.ToString(); + } + + /// + /// This will return the existing expression or ConstantExpression(Value) if the value is non-complex type. + /// + /// expression. + public Expression ToExpression() + { + if (this.Expression != null) + { + return this.Expression; + } + + if (this.Value is string || this.Value.IsNumber() || this.Value.IsInteger() || this.Value is bool || this.Value.GetType().IsEnum) + { + return new ExpressionEngine().Parse(this.Value.ToString()); + } + + // return expression for json object + return new ExpressionEngine().Parse($"json({JsonConvert.SerializeObject(this.Value)})"); + } + + /// + /// Get the value. + /// + /// data to use for expression binding. + /// value or default(T) if not found. + public virtual T GetValue(object data) + { + return this.TryGetValue(data).Value; + } + + /// + /// try to Get the value. + /// + /// data to use for expression binding. + /// value. + public virtual (T Value, string Error) TryGetValue(object data) + { + if (Expression != null) + { + return Expression.TryEvaluate(data); + } + + return (Value, null); + } + + /// + /// Set the value. + /// + /// value to set. + public virtual void SetValue(object value) + { + this.Value = default(T); + this.Expression = null; + + if (value == null) + { + this.Value = default(T); + this.Expression = null; + return; + } + + if (value is string stringOrExpression) + { + Expression = new ExpressionEngine().Parse(stringOrExpression.TrimStart('=')); + return; + } + + this.Value = ConvertObject(value); + } + + /// + /// Convert raw object to desired value type. + /// + /// + /// This method is called whenever an object is fected via expression or is deserialized from raw text. + /// + /// result to convert to object of type T. + /// object of type T. + protected virtual T ConvertObject(object result) + { + if (result is T) + { + return (T)result; + } + + if (result == null) + { + return default(T); + } + + return JToken.FromObject(result).ToObject(); + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/IntExpression.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/IntExpression.cs new file mode 100644 index 0000000000..f5decbb0ad --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/IntExpression.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive +{ + /// + /// IntExpression - represents a property which is either an Integer or a string expression which resolves to a Integer. + /// + /// String values are always interpreted as an expression, whether it has '=' prefix or not. + [JsonConverter(typeof(IntExpressionConverter))] + public class IntExpression : ExpressionProperty + { + /// + /// Initializes a new instance of the class. + /// + public IntExpression() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// value to return. + public IntExpression(int value) + : base(value) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// string expression to resolve to an int. + public IntExpression(string expression) + : base(expression) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// JToken to resolve to an int. + public IntExpression(JToken value) + : base(value) + { + } + + public static implicit operator IntExpression(int value) => new IntExpression(value); + + public static implicit operator IntExpression(string value) => new IntExpression(value); + + public static implicit operator IntExpression(JToken value) => new IntExpression(value); + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/NumberExpression.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/NumberExpression.cs new file mode 100644 index 0000000000..4ebff2d8c1 --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/NumberExpression.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive +{ + /// + /// NumberExpression - represents a property which is either a float or a string expression which resolves to a float. + /// + /// String values are always interpreted as an expression, whether it has '=' prefix or not. + [JsonConverter(typeof(NumberExpressionConverter))] + public class NumberExpression : ExpressionProperty + { + /// + /// Initializes a new instance of the class. + /// + public NumberExpression() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// value to use. + public NumberExpression(float value) + : base(value) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// string to interpret as expression or number. + public NumberExpression(string expression) + : base(expression) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// jtoken to interpret as expression or number. + public NumberExpression(JToken value) + : base(value) + { + } + + public static implicit operator NumberExpression(float value) => new NumberExpression(value); + + public static implicit operator NumberExpression(string value) => new NumberExpression(value); + + public static implicit operator NumberExpression(JToken value) => new NumberExpression(value); + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ObjectExpression.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ObjectExpression.cs new file mode 100644 index 0000000000..82fb8f2bda --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ObjectExpression.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive +{ + /// + /// ObjectExpression(T) - represents a property which is either an object of type T or a string expression which resolves to a object of type T. + /// + /// the type of object. + /// String values are always interpreted as an expression, whether it has '=' prefix or not. + public class ObjectExpression : ExpressionProperty + { + public ObjectExpression() + { + } + + public ObjectExpression(T value) + : base(value) + { + } + + public ObjectExpression(string expressionOrString) + : base(expressionOrString) + { + } + + public ObjectExpression(JToken value) + : base(value) + { + } + + public static implicit operator ObjectExpression(T value) => new ObjectExpression(value); + + public static implicit operator ObjectExpression(string value) => new ObjectExpression(value); + + public static implicit operator ObjectExpression(JToken value) => new ObjectExpression(value); + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/StringExpression.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/StringExpression.cs new file mode 100644 index 0000000000..66b758122b --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/StringExpression.cs @@ -0,0 +1,96 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; +using Microsoft.Bot.Builder.LanguageGeneration; +using Microsoft.Bot.Expressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive +{ + /// + /// StringExpression - represents a property which is either a string value or a string expression. + /// + /// + /// If the value is + /// * a string with '=' prefix then the string is treated as an expression to resolve to a string. + /// * a string without '=' then value is treated as string with string interpolation. + /// * You can escape the '=' prefix by putting a backslash. + /// Examples: + /// prop = "Hello @{user.name}" => "Hello Joe" + /// prop = "=length(user.name)" => "3" + /// prop = "=user.name" => "Joe" + /// prop = "\=user" => "=user". + /// + [JsonConverter(typeof(StringExpressionConverter))] + public class StringExpression : ExpressionProperty + { + private LGFile lg = new LGFile(); + + /// + /// Initializes a new instance of the class. + /// + public StringExpression() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// string to interpret as string or expression to a string. + public StringExpression(string valueOrExpression) + : base(valueOrExpression) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// value to interpret as a string or expression to a string. + public StringExpression(JToken value) + : base(value) + { + } + + public static implicit operator StringExpression(string valueOrExpression) => new StringExpression(valueOrExpression); + + public static implicit operator StringExpression(JToken value) => new StringExpression(value); + + public override (string Value, string Error) TryGetValue(object data) + { + if (this.Value != null) + { + // interpolated string + return (lg.Evaluate(this.Value, data).ToString(), null); + } + + return base.TryGetValue(data); + } + + public override void SetValue(object value) + { + var stringOrExpression = (value as string) ?? (value as JValue)?.Value as string; + + if (stringOrExpression != null) + { + // if it starts with = it always is an expression + if (stringOrExpression.StartsWith("=")) + { + Expression = new ExpressionEngine().Parse(stringOrExpression.TrimStart('=')); + return; + } + else if (stringOrExpression.StartsWith("\\=")) + { + // then trim off the escape char for equals (\=foo) should simply be the string (=foo), and not an expression (but it could still be stringTemplate) + stringOrExpression = stringOrExpression.TrimStart('\\'); + } + + this.Value = stringOrExpression; + return; + } + + base.SetValue(value); + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ValueExpression.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ValueExpression.cs new file mode 100644 index 0000000000..3518c387c7 --- /dev/null +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Memory/Expressions/ValueExpression.cs @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; +using Microsoft.Bot.Builder.LanguageGeneration; +using Microsoft.Bot.Expressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive +{ + /// + /// ValueExpression - represents a property which is an object of any kind or a string expression. + /// + /// + /// If the value is + /// * a string with '=' prefix then the string is treated as an expression to resolve to a string. + /// * a string without '=' then value is treated as string with string interpolation. + /// * any other type, then it is of that type (int, bool, object, etc.) + /// You can escape the '=' prefix by putting a backslash. + /// Examples: + /// prop = true ==> true + /// prop = "Hello @{user.name}" => "Hello Joe" + /// prop = "=length(user.name)" => 3 + /// prop = "=user.age" => 45. + /// prop = "\=user.age" => "=user.age". + /// + [JsonConverter(typeof(ValueExpressionConverter))] + public class ValueExpression : ExpressionProperty + { + private LGFile lg = new LGFile(); + + /// + /// Initializes a new instance of the class. + /// + public ValueExpression() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// value to interpret as object or string expression. + public ValueExpression(object value) + : base(value) + { + } + + public static implicit operator ValueExpression(string valueOrExpression) => new ValueExpression(valueOrExpression); + + public static implicit operator ValueExpression(JToken value) => new ValueExpression(value); + + public override (object Value, string Error) TryGetValue(object data) + { + if (this.Value != null && this.Value is string val) + { + // value is a string (not an expression) should be interpreted as string, which means interperlated + return (lg.Evaluate(val, data).ToString(), null); + } + + return base.TryGetValue(data); + } + + public override void SetValue(object value) + { + var stringOrExpression = (value as string) ?? (value as JValue)?.Value as string; + + if (stringOrExpression != null) + { + // if it starts with = it always is an expression + if (stringOrExpression.StartsWith("=")) + { + Expression = new ExpressionEngine().Parse(stringOrExpression.TrimStart('=')); + return; + } + else if (stringOrExpression.StartsWith("\\=")) + { + // then trim off the escape char for equals (\=foo) should simply be the string (=foo), and not an expression (but it could still be stringTemplate) + stringOrExpression = stringOrExpression.TrimStart('\\'); + } + + this.Value = stringOrExpression; + return; + } + + base.SetValue(value); + } + } +} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerComponentRegistration.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerComponentRegistration.cs index 7c7ac890a4..03fa6e0500 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerComponentRegistration.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerComponentRegistration.cs @@ -2,6 +2,8 @@ // Licensed under the MIT License. using System.Collections.Generic; +using Microsoft.Bot.Builder.Dialogs.Adaptive; +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; using Microsoft.Bot.Builder.Dialogs.Adaptive.QnA; using Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers; using Microsoft.Bot.Builder.Dialogs.Debugging; @@ -24,6 +26,8 @@ public override IEnumerable GetTypes() public override IEnumerable GetConverters(ISourceMap sourceMap, IRefResolver refResolver, Stack paths) { + yield return new ArrayExpressionConverter(); + yield break; } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerDialog2.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerDialog2.cs index 68306c5bac..77ee713254 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerDialog2.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerDialog2.cs @@ -14,10 +14,6 @@ public class QnAMakerDialog2 : QnAMakerDialog [JsonProperty("$kind")] public const string DeclarativeType = "Microsoft.QnAMakerDialog"; - private Expression knowledgebaseIdExpression; - private Expression endpointkeyExpression; - private Expression hostnameExpression; - [JsonConstructor] public QnAMakerDialog2([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) : base(sourceFilePath, sourceLineNumber) @@ -31,11 +27,7 @@ public QnAMakerDialog2([CallerFilePath] string sourceFilePath = "", [CallerLineN /// The knowledgebase Id. /// [JsonProperty("knowledgeBaseId")] - public string KnowledgeBaseId - { - get { return knowledgebaseIdExpression?.ToString(); } - set { knowledgebaseIdExpression = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public StringExpression KnowledgeBaseId { get; set; } /// /// Gets or sets the Hostname for your QnA Maker service. @@ -44,11 +36,7 @@ public string KnowledgeBaseId /// The host name of the QnA Maker knowledgebase. /// [JsonProperty("hostname")] - public string HostName - { - get { return hostnameExpression?.ToString(); } - set { hostnameExpression = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public StringExpression HostName { get; set; } /// /// Gets or sets the Endpoint key for the QnA Maker KB. @@ -57,11 +45,7 @@ public string HostName /// The endpoint key for the QnA service. /// [JsonProperty("endpointKey")] - public string EndpointKey - { - get { return endpointkeyExpression?.ToString(); } - set { endpointkeyExpression = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public StringExpression EndpointKey { get; set; } /// /// Gets or sets the Threshold score to filter results. @@ -70,7 +54,7 @@ public string EndpointKey /// The threshold for the results. /// [JsonProperty("threshold")] - public float Threshold { get; set; } = DefaultThreshold; + public NumberExpression Threshold { get; set; } = DefaultThreshold; /// /// Gets or sets the number of results you want. @@ -79,7 +63,7 @@ public string EndpointKey /// The number of results you want. /// [JsonProperty("top")] - public int Top { get; set; } = DefaultTopN; + public IntExpression Top { get; set; } = DefaultTopN; /// /// Gets or sets the template for Default answer to return when none found in KB. @@ -97,7 +81,7 @@ public string EndpointKey /// Title for active learning suggestions card. /// [JsonProperty("activeLearningCardTitle")] - public string ActiveLearningCardTitle { get; set; } + public StringExpression ActiveLearningCardTitle { get; set; } /// /// Gets or sets the Text for no match option. @@ -106,7 +90,7 @@ public string EndpointKey /// The Text for no match option. /// [JsonProperty("cardNoMatchText")] - public string CardNoMatchText { get; set; } + public StringExpression CardNoMatchText { get; set; } /// /// Gets or sets the template for Custom response when no match option was selected. @@ -124,7 +108,7 @@ public string EndpointKey /// The metadata strict filters. /// [JsonProperty("strictFilters")] - public Metadata[] StrictFilters { get; set; } + public ArrayExpression StrictFilters { get; set; } /// /// Gets or sets a value indicating whether gets or sets environment of knowledgebase to be called. @@ -142,10 +126,12 @@ public string EndpointKey /// Ranker Types. /// [JsonProperty("rankerType")] - public string RankerType { get; set; } = RankerTypes.DefaultRankerType; + public StringExpression RankerType { get; set; } = new StringExpression(RankerTypes.DefaultRankerType); protected async override Task GetQnAMakerClientAsync(DialogContext dc) { + var dcState = dc.GetState(); + var qnaClient = dc.Context.TurnState.Get(); if (qnaClient != null) { @@ -153,9 +139,9 @@ protected async override Task GetQnAMakerClientAsync(DialogCont return qnaClient; } - var (epKey, error) = this.endpointkeyExpression.TryEvaluate(dc.GetState()); - var (hn, error2) = this.hostnameExpression.TryEvaluate(dc.GetState()); - var (kbId, error3) = this.knowledgebaseIdExpression.TryEvaluate(dc.GetState()); + var (epKey, error) = this.EndpointKey.TryGetValue(dcState); + var (hn, error2) = this.HostName.TryGetValue(dcState); + var (kbId, error3) = this.KnowledgeBaseId.TryGetValue(dcState); var endpoint = new QnAMakerEndpoint { @@ -169,26 +155,29 @@ protected async override Task GetQnAMakerClientAsync(DialogCont protected override Task GetQnAMakerOptionsAsync(DialogContext dc) { + var dcState = dc.GetState(); + return Task.FromResult(new QnAMakerOptions { - ScoreThreshold = this.Threshold, - StrictFilters = this.StrictFilters, - Top = this.Top, + ScoreThreshold = this.Threshold.GetValue(dcState), + StrictFilters = this.StrictFilters?.GetValue(dcState)?.ToArray(), + Top = this.Top.GetValue(dcState), QnAId = 0, - RankerType = this.RankerType, + RankerType = this.RankerType.GetValue(dcState), IsTest = this.IsTest }); } protected async override Task GetQnAResponseOptionsAsync(DialogContext dc) { - var noAnswer = (this.NoAnswer != null) ? await this.NoAnswer.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false) : null; - var cardNoMatchResponse = (this.CardNoMatchResponse != null) ? await this.CardNoMatchResponse.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false) : null; + var dcState = dc.GetState(); + var noAnswer = (this.NoAnswer != null) ? await this.NoAnswer.BindToData(dc.Context, dcState).ConfigureAwait(false) : null; + var cardNoMatchResponse = (this.CardNoMatchResponse != null) ? await this.CardNoMatchResponse.BindToData(dc.Context, dcState).ConfigureAwait(false) : null; var responseOptions = new QnADialogResponseOptions { - ActiveLearningCardTitle = this.ActiveLearningCardTitle, - CardNoMatchText = this.CardNoMatchText, + ActiveLearningCardTitle = this.ActiveLearningCardTitle.GetValue(dcState), + CardNoMatchText = this.CardNoMatchText.GetValue(dcState), NoAnswer = noAnswer, CardNoMatchResponse = cardNoMatchResponse, }; diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerRecognizer.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerRecognizer.cs index ccb9b6f848..a230b46058 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerRecognizer.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/QnAMaker/QnAMakerRecognizer.cs @@ -6,13 +6,9 @@ using System.ComponentModel; using System.Linq; using System.Net.Http; -using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Microsoft.Bot.Builder.AI.QnA; -using Microsoft.Bot.Expressions; -using Microsoft.Bot.Schema; -using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -30,10 +26,6 @@ public class QnAMakerRecognizer : Recognizer private const string IntentPrefix = "intent="; - private Expression knowledgebaseIdExpression; - private Expression endpointkeyExpression; - private Expression hostnameExpression; - public QnAMakerRecognizer() { } @@ -45,11 +37,7 @@ public QnAMakerRecognizer() /// The knowledgebase Id. /// [JsonProperty("knowledgeBaseId")] - public string KnowledgeBaseId - { - get { return knowledgebaseIdExpression?.ToString(); } - set { knowledgebaseIdExpression = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public StringExpression KnowledgeBaseId { get; set; } /// /// Gets or sets the Hostname for your QnA Maker service. @@ -58,11 +46,7 @@ public string KnowledgeBaseId /// The host name of the QnA Maker knowledgebase. /// [JsonProperty("hostname")] - public string HostName - { - get { return hostnameExpression?.ToString(); } - set { hostnameExpression = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public StringExpression HostName { get; set; } /// /// Gets or sets the Endpoint key for the QnA Maker KB. @@ -71,11 +55,7 @@ public string HostName /// The endpoint key for the QnA service. /// [JsonProperty("endpointKey")] - public string EndpointKey - { - get { return endpointkeyExpression?.ToString(); } - set { endpointkeyExpression = value != null ? new ExpressionEngine().Parse(value) : null; } - } + public StringExpression EndpointKey { get; set; } /// /// Gets or sets the number of results you want. @@ -85,7 +65,7 @@ public string EndpointKey /// [DefaultValue(3)] [JsonProperty("top")] - public int Top { get; set; } = 3; + public IntExpression Top { get; set; } = 3; /// /// Gets or sets the threshold score to filter results. @@ -95,7 +75,7 @@ public string EndpointKey /// [DefaultValue(0.3F)] [JsonProperty("threshold")] - public float Threshold { get; set; } = 0.3F; + public NumberExpression Threshold { get; set; } = 0.3F; /// /// Gets or sets a value indicating whether gets or sets environment of knowledgebase to be called. @@ -113,13 +93,15 @@ public string EndpointKey /// The desired RankerType. /// [JsonProperty("rankerType")] - public string RankerType { get; set; } = RankerTypes.DefaultRankerType; + public StringExpression RankerType { get; set; } = RankerTypes.DefaultRankerType; [JsonIgnore] public HttpClient HttpClient { get; set; } public override async Task RecognizeAsync(DialogContext dialogContext, string text, string locale, CancellationToken cancellationToken) { + var dcState = dialogContext.GetState(); + // Identify matched intents var utterance = text ?? string.Empty; @@ -135,7 +117,7 @@ public override async Task RecognizeAsync(DialogContext dialog }; // if there is $qna.metadata set add to filters - var externalMetadata = dialogContext.GetState().GetValue("$qna.metadata"); + var externalMetadata = dcState.GetValue("$qna.metadata"); if (externalMetadata != null) { filters.AddRange(externalMetadata); @@ -147,12 +129,12 @@ public override async Task RecognizeAsync(DialogContext dialog dialogContext.Context, new QnAMakerOptions { - Context = dialogContext.GetState().GetValue("$qna.context"), - ScoreThreshold = this.Threshold, + Context = dcState.GetValue("$qna.context"), + ScoreThreshold = this.Threshold.TryGetValue(dcState).Value, StrictFilters = filters.ToArray(), - Top = this.Top, + Top = this.Top.TryGetValue(dcState).Value, QnAId = 0, - RankerType = this.RankerType, + RankerType = this.RankerType.TryGetValue(dcState).Value, IsTest = this.IsTest }, null).ConfigureAwait(false); @@ -204,9 +186,11 @@ protected virtual Task GetQnAMakerClientAsync(DialogContext dc) return Task.FromResult(qnaClient); } - var (epKey, error) = this.endpointkeyExpression.TryEvaluate(dc.GetState()); - var (hn, error2) = this.hostnameExpression.TryEvaluate(dc.GetState()); - var (kbId, error3) = this.knowledgebaseIdExpression.TryEvaluate(dc.GetState()); + var dcState = dc.GetState(); + + var (epKey, error) = this.EndpointKey.TryGetValue(dcState); + var (hn, error2) = this.HostName.TryGetValue(dcState); + var (kbId, error3) = this.KnowledgeBaseId.TryGetValue(dcState); var endpoint = new QnAMakerEndpoint { diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Recognizers/IntentPattern.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Recognizers/IntentPattern.cs index 8351a90e3d..d19598f191 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Recognizers/IntentPattern.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Recognizers/IntentPattern.cs @@ -50,7 +50,7 @@ public string Pattern set { this.pattern = value; - this.regex = new Regex(pattern, RegexOptions.Compiled); + this.regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Recognizers/RegexRecognizer.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Recognizers/RegexRecognizer.cs index 256a612d23..77bf1e8c20 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Recognizers/RegexRecognizer.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Recognizers/RegexRecognizer.cs @@ -7,6 +7,7 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Bot.Builder.TraceExtensions; using Microsoft.Bot.Schema; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -50,7 +51,7 @@ public override async Task RecognizeAsync(DialogContext dialog // Identify matched intents text = text ?? string.Empty; - var result = new RecognizerResult() + var recognizerResult = new RecognizerResult() { Text = text, Intents = new Dictionary(), @@ -74,9 +75,13 @@ public override async Task RecognizeAsync(DialogContext dialog { // TODO length weighted match and multiple intents var intentKey = intentPattern.Intent.Replace(" ", "_"); - if (!result.Intents.ContainsKey(intentKey)) + if (!recognizerResult.Intents.ContainsKey(intentKey)) { - result.Intents.Add(intentKey, new IntentScore() { Score = 1.0 }); + recognizerResult.Intents.Add(intentKey, new IntentScore() + { + Score = 1.0, + Properties = new Dictionary() { { "pattern", intentPattern.Pattern } } + }); } // Check for named capture groups @@ -115,16 +120,16 @@ public override async Task RecognizeAsync(DialogContext dialog } // map entityPool of Entity objects => RecognizerResult entity format - result.Entities = new JObject(); - + recognizerResult.Entities = new JObject(); + foreach (var entityResult in entityPool) { // add value JToken values; - if (!result.Entities.TryGetValue(entityResult.Type, StringComparison.OrdinalIgnoreCase, out values)) + if (!recognizerResult.Entities.TryGetValue(entityResult.Type, StringComparison.OrdinalIgnoreCase, out values)) { values = new JArray(); - result.Entities[entityResult.Type] = values; + recognizerResult.Entities[entityResult.Type] = values; } // The Entity type names are not consistent, map everything to camelcase so we can process them cleaner. @@ -133,10 +138,10 @@ public override async Task RecognizeAsync(DialogContext dialog // get/create $instance JToken instanceRoot; - if (!result.Entities.TryGetValue("$instance", StringComparison.OrdinalIgnoreCase, out instanceRoot)) + if (!recognizerResult.Entities.TryGetValue("$instance", StringComparison.OrdinalIgnoreCase, out instanceRoot)) { instanceRoot = new JObject(); - result.Entities["$instance"] = instanceRoot; + recognizerResult.Entities["$instance"] = instanceRoot; } // add instanceData @@ -158,12 +163,14 @@ public override async Task RecognizeAsync(DialogContext dialog } // if no match return None intent - if (!result.Intents.Keys.Any()) + if (!recognizerResult.Intents.Keys.Any()) { - result.Intents.Add("None", new IntentScore() { Score = 1.0 }); + recognizerResult.Intents.Add("None", new IntentScore() { Score = 1.0 }); } - return result; + await dialogContext.Context.TraceActivityAsync(nameof(RegexRecognizer), JObject.FromObject(recognizerResult), "RecognizerResult", "Regex RecognizerResult", cancellationToken).ConfigureAwait(false); + + return recognizerResult; } } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.BeginDialog.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.BeginDialog.schema index 963204f0c9..232e005a9e 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.BeginDialog.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.BeginDialog.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string"], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -20,6 +21,8 @@ }, "dialog": { "$kind": "Microsoft.IDialog", + "$role": "expression", + "type": ["string", "object"], "title": "Dialog name", "description": "Name of the dialog to call.", "examples": [ @@ -27,7 +30,8 @@ ] }, "options": { - "type": "object", + "$role": "expression", + "type": [ "string", "object" ], "title": "Options", "description": "One or more options that are passed to the dialog that is called.", "additionalProperties": { @@ -36,13 +40,15 @@ } }, "activityProcessed": { - "type": "boolean", + "$role": "expression", + "type": [ "boolean", "string" ], "title": "Activity Processed", "description": "When set to false, the dialog that is called can process the current activity.", "default": true }, "resultProperty": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store any value returned by the dialog that is called.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.BreakLoop.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.BreakLoop.schema index c7f8ee2b51..ef59ead84f 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.BreakLoop.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.BreakLoop.schema @@ -13,6 +13,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.CancelAllDialogs.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.CancelAllDialogs.schema index aea015d303..5b8f25b228 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.CancelAllDialogs.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.CancelAllDialogs.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -19,12 +20,14 @@ ] }, "eventName": { + "$role": "expression", + "type": "string", "title": "Event name", - "description": "Name of the event to emit.", - "type": "string" + "description": "Name of the event to emit." }, "eventValue": { - "type": "object", + "$role": "expression", + "type": [ "object", "array", "number", "integer", "boolean", "string" ], "title": "Event value", "description": "Value to emit with the event (optional).", "additionalProperties": true diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ContinueLoop.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ContinueLoop.schema index b1c5b61f0f..2308620f1b 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ContinueLoop.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ContinueLoop.schema @@ -13,6 +13,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DebugBreak.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DebugBreak.schema index 0826b92055..0c7da75e0b 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DebugBreak.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DebugBreak.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteActivity.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteActivity.schema index 2c6dec392a..1436e1a76c 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteActivity.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteActivity.schema @@ -16,14 +16,16 @@ }, "activityId": { "$role": "expression", + "type": "string", "title": "ActivityId", "description": "expression to an activityId to delete", "examples": [ - "$lastActivity" + "=$lastActivity" ] }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteProperties.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteProperties.schema index dfda29b732..0f3191eaa5 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteProperties.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteProperties.schema @@ -15,6 +15,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -27,6 +28,7 @@ "description": "Properties to delete.", "items": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to delete." } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteProperty.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteProperty.schema index f5a87ab0b7..eaa9f4ff5c 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteProperty.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.DeleteProperty.schema @@ -15,6 +15,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -23,6 +24,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to delete." } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EditActions.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EditActions.schema index 2b49e5ecda..700c083549 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EditActions.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EditActions.schema @@ -16,6 +16,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -23,6 +24,7 @@ ] }, "changeType": { + "$role": "expression", "type": "string", "title": "Type of change", "description": "Type of change to apply to the current actions.", diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EditArray.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EditArray.schema index fc92007a14..cdc0869769 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EditArray.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EditArray.schema @@ -15,6 +15,7 @@ "description": "Optional id for the dialog" }, "changeType": { + "$role": "expression", "type": "string", "title": "Type of change", "description": "Type of change to the array in memory.", @@ -28,6 +29,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -36,16 +38,19 @@ }, "itemsProperty": { "$role": "expression", + "type": "string", "title": "Items property", "description": "Property that holds the array to update." }, "resultProperty": { "$role": "expression", + "type": "string", "title": "Result Property", "description": "Property to store the result of this action." }, "value": { "$role": "expression", + "type": [ "object", "array", "number", "integer", "boolean", "string" ], "title": "Value", "description": "New value or expression.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EmitEvent.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EmitEvent.schema index ae3e66bac1..2bd5af02ae 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EmitEvent.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EmitEvent.schema @@ -15,6 +15,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -22,37 +23,34 @@ ] }, "eventName": { + "$role": "expression", + "type": "string", "title": "Event name", "description": "Name of the event to emit.", - "anyOf": [ - { - "enum": [ - "beginDialog", - "resumeDialog", - "repromptDialog", - "cancelDialog", - "endDialog", - "activityReceived", - "recognizedIntent", - "unknownIntent", - "actionsStarted", - "actionsSaved", - "actionsEnded", - "actionsResumed" - ] - }, - { - "type": "string" - } + "enum": [ + "beginDialog", + "resumeDialog", + "repromptDialog", + "cancelDialog", + "endDialog", + "activityReceived", + "recognizedIntent", + "unknownIntent", + "actionsStarted", + "actionsSaved", + "actionsEnded", + "actionsResumed" ] }, "eventValue": { "$role": "expression", + "type": [ "object", "array", "number", "integer", "boolean", "string" ], "title": "Event value", "description": "Value to emit with the event (optional)." }, "bubbleEvent": { - "type": "boolean", + "$role": "expression", + "type": [ "boolean", "string" ], "title": "Bubble event", "description": "If true this event is passed on to parent dialogs.", "default": false diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EndDialog.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EndDialog.schema index 2c95c06055..caecc1846d 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EndDialog.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EndDialog.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -20,11 +21,12 @@ }, "value": { "$role": "expression", + "type": [ "object", "array", "number", "integer", "boolean", "string" ], "title": "Value", "description": "Result value returned to the parent dialog.", "examples": [ - "dialog.userName", - "'tomato'" + "=dialog.userName", + "='tomato'" ] } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EndTurn.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EndTurn.schema index d8a8c05ac0..918c7a474c 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EndTurn.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.EndTurn.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.Foreach.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.Foreach.schema index 42578bec3d..e80c089c9d 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.Foreach.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.Foreach.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -20,6 +21,7 @@ }, "itemsProperty": { "$role": "expression", + "type": [ "string" ], "title": "Items property", "description": "Property that holds the array.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ForeachPage.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ForeachPage.schema index a809d85feb..0cb62697d2 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ForeachPage.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ForeachPage.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -20,6 +21,7 @@ }, "itemsProperty": { "$role": "expression", + "type": "string", "title": "Items property", "description": "Property that holds the array.", "examples": [ @@ -35,7 +37,8 @@ "description": "Actions to execute for each page. Use '$foreach.page' to access each page." }, "pageSize": { - "type": "integer", + "$role": "expression", + "type": [ "integer", "string" ], "title": "Page size", "description": "Number of items in each page.", "default": 10 diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GetActivityMembers.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GetActivityMembers.schema index 86bf59c522..13ed133d9a 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GetActivityMembers.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GetActivityMembers.schema @@ -12,6 +12,7 @@ }, "activityId": { "$role": "expression", + "type": "string", "title": "ActivityId", "description": "expression to an activityId to get the members. If none is defined then the current activity id will be used.", "examples": [ @@ -20,6 +21,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GetConversationMembers.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GetConversationMembers.schema index c7d869abe3..f489b70b63 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GetConversationMembers.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GetConversationMembers.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GotoAction.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GotoAction.schema index 1cbb93d438..192d6508c4 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GotoAction.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.GotoAction.schema @@ -15,6 +15,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -22,6 +23,7 @@ ] }, "actionId": { + "$role": "expression", "type": "string", "title": "Action Id", "description": "Action Id to execute next" diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.HttpRequest.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.HttpRequest.schema index 4938acaf62..8b61494464 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.HttpRequest.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.HttpRequest.schema @@ -16,6 +16,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -39,6 +40,7 @@ ] }, "url": { + "$role": "expression", "type": "string", "title": "Url", "description": "URL to call (supports data binding).", @@ -47,13 +49,15 @@ ] }, "body": { - "type": "object", + "$role": "expression", + "type": [ "object", "array", "number", "integer", "boolean", "string" ], "title": "Body", "description": "Body to include in the HTTP call (supports data binding).", "additionalProperties": true }, "resultProperty": { "$role": "expression", + "type": "string", "title": "Result property", "description": "Property to store the result of this action. The result includes 4 properties from the http response: statusCode, reasonPhrase, content and headers. If the content is json it will be a deserialized object.", "examples": [ @@ -62,11 +66,15 @@ }, "headers": { "type": "object", - "additionalProperties": true, + "additionalProperties": { + "$role": "expression", + "type": "string" + }, "title": "Headers", "description": "One or more headers to include in the request (supports data binding)." }, "responseType": { + "$role": "expression", "type": "string", "title": "Response type", "description": "Defines the type of HTTP response. Automatically calls the 'Send a response' action if set to 'Activity' or 'Activities'.", diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.IfCondition.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.IfCondition.schema index e5ea5329e1..8cae6b1715 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.IfCondition.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.IfCondition.schema @@ -16,6 +16,7 @@ }, "condition": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Condition", "description": "Expression to evaluate.", "examples": [ @@ -24,6 +25,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.InitProperty.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.InitProperty.schema index a62a27f362..93d512da29 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.InitProperty.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.InitProperty.schema @@ -16,6 +16,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -24,6 +25,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property (named location to store information).", "examples": [ @@ -31,6 +33,7 @@ ] }, "type": { + "$role": "expression", "type": "string", "title": "Type", "description": "Type of value.", diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.LogAction.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.LogAction.schema index ab5b38730e..b86c33e027 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.LogAction.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.LogAction.schema @@ -15,6 +15,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -22,17 +23,20 @@ ] }, "text": { + "$role": "expression", "type": "string", "title": "Text", "description": "Information to log." }, "label": { + "$role": "expression", "type": "string", "title": "Label", "description": "Label for the trace activity (used to identify it in a list of trace activities.)" }, "traceActivity": { - "type": "boolean", + "$role": "expression", + "type": [ "boolean", "string" ], "title": "Send Trace Activity", "description": "If true, automatically sends a TraceActivity (view in Bot Framework Emulator).", "default": false diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.RepeatDialog.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.RepeatDialog.schema index fe3826ffb0..197d23d87d 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.RepeatDialog.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.RepeatDialog.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -19,7 +20,8 @@ ] }, "options": { - "type": "object", + "$role": "expression", + "type": [ "string", "object" ], "title": "Options", "description": "One or more options that are passed to the dialog that is called.", "additionalProperties": { @@ -28,7 +30,8 @@ } }, "activityProcessed": { - "type": "boolean", + "$role": "expression", + "type": [ "boolean", "string" ], "title": "Activity Processed", "description": "When set to false, the dialog that is called can process the current activity.", "default": true diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ReplaceDialog.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ReplaceDialog.schema index 956b787d00..f9488a77f8 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ReplaceDialog.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ReplaceDialog.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -20,6 +21,8 @@ }, "dialog": { "$kind": "Microsoft.IDialog", + "$role": "expression", + "type": ["string", "object"], "title": "Dialog name", "description": "Name of the dialog to call.", "examples": [ @@ -27,7 +30,8 @@ ] }, "options": { - "type": "object", + "$role": "expression", + "type": [ "string", "object" ], "title": "Options", "description": "One or more options that are passed to the dialog that is called.", "additionalProperties": { @@ -36,7 +40,8 @@ } }, "activityProcessed": { - "type": "boolean", + "$role": "expression", + "type": [ "boolean", "string" ], "title": "Activity Processed", "description": "When set to false, the dialog that is called can process the current activity.", "default": true diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SendActivity.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SendActivity.schema index ddfdae9e87..5a7042ffbf 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SendActivity.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SendActivity.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SetProperties.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SetProperties.schema index d9754bd203..d24df64ad1 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SetProperties.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SetProperties.schema @@ -15,6 +15,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -30,6 +31,7 @@ "properties": { "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property (named location to store information).", "examples": [ @@ -38,12 +40,13 @@ }, "value": { "$role": "expression", + "type": [ "object", "array", "number", "integer", "boolean", "string" ], "title": "Value", "description": "New value or expression.", "examples": [ - "'milk'", - "dialog.favColor", - "dialog.favColor == 'red'" + "='milk'", + "=dialog.favColor", + "=dialog.favColor == 'red'" ] } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SetProperty.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SetProperty.schema index ecfedcfafa..dd115df02e 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SetProperty.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SetProperty.schema @@ -16,6 +16,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -24,6 +25,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property (named location to store information).", "examples": [ @@ -32,12 +34,13 @@ }, "value": { "$role": "expression", + "type": [ "object", "array", "number", "integer", "boolean", "string" ], "title": "Value", "description": "New value or expression.", "examples": [ - "'milk'", - "dialog.favColor", - "dialog.favColor == 'red'" + "='milk'", + "=dialog.favColor", + "=dialog.favColor == 'red'" ] } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SignOutUser.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SignOutUser.schema index 67f44396c5..89ecbd1220 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SignOutUser.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SignOutUser.schema @@ -12,19 +12,22 @@ }, "userId": { "$role": "expression", + "type": "string", "title": "ActivityId", "description": "expression to an activityId to get the members. If none is defined then the current activity id will be used.", "examples": [ - "$lastActivity" + "=$lastActivity" ] }, "connectionName": { + "$role": "expression", "type": "string", "title": "Connection Name", "description": "Connection name that was used with OAuthInput to log a user in." }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SwitchCondition.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SwitchCondition.schema index e385aae156..f8472c6e78 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SwitchCondition.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.SwitchCondition.schema @@ -15,6 +15,7 @@ }, "condition": { "$role": "expression", + "type": "string", "title": "Condition", "description": "Property to evaluate.", "examples": [ @@ -23,6 +24,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -38,6 +40,7 @@ "properties": { "value": { "$role": "expression", + "type": [ "number", "integer", "boolean", "string" ], "title": "Value", "description": "Value.", "examples": [ diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.TraceActivity.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.TraceActivity.schema index b510d575d5..b86b0a0a0b 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.TraceActivity.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.TraceActivity.schema @@ -12,6 +12,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -19,22 +20,26 @@ ] }, "name": { + "$role": "expression", "type": "string", "title": "Name", "description": "Name of the trace activity" }, "label": { + "$role": "expression", "type": "string", "title": "Label", "description": "Label for the trace activity (used to identify it in a list of trace activities.)" }, "valueType": { + "$role": "expression", "type": "string", "title": "Value type", "description": "Type of value" }, "value": { "$role": "expression", + "type": [ "object", "array", "number", "integer", "boolean", "string" ], "title": "Value", "description": "Property that holds the value to send as trace activity." } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.UpdateActivity.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.UpdateActivity.schema index 3ac89a9bff..f010896ef8 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.UpdateActivity.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.UpdateActivity.schema @@ -10,6 +10,24 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ "boolean", "string" ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, + "activityId": { + "$role": "expression", + "type": "string", + "title": "Activity Id", + "dDescription": "An string expression with the activity id to update.", + "examples": [ + "=dialog.lastActivityId" + ] + }, "activity": { "$kind": "Microsoft.IActivityTemplate", "title": "Activity", diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.Ask.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.Ask.schema index e8e7b8596b..94b1b64867 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.Ask.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.Ask.schema @@ -11,14 +11,15 @@ { "properties": { "expectedProperties": { + "$role": "expression", + "title": "Expected Properties", + "description": "Properties expected to be filled by entities from the user", "oneOf": [ { "type": "array", "items": { "type": "string" - }, - "title": "Expected Properties", - "description": "Properties expected to be filled by entities from the user" + } }, { "type": "string" diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.AttachmentInput.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.AttachmentInput.schema index d20a424258..34eeb88556 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.AttachmentInput.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.AttachmentInput.schema @@ -10,6 +10,7 @@ { "properties": { "outputFormat": { + "$role": "expression", "type": "string", "enum": [ "all", diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.ChoiceInput.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.ChoiceInput.schema index 1f5e449941..7a5ceaaf5e 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.ChoiceInput.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.ChoiceInput.schema @@ -11,6 +11,7 @@ { "properties": { "outputFormat": { + "$role": "expression", "type": "string", "enum": [ "value", diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.ConfirmInput.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.ConfirmInput.schema index 53615a5ba8..e9826aa210 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.ConfirmInput.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.ConfirmInput.schema @@ -12,19 +12,22 @@ "properties": { "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the confirm output.", "examples": [ - "concat('confirmation:', this.value)" + "=concat('confirmation:', this.value)" ] }, "defaultLocale": { + "$role": "expression", "type": "string", "title": "Default locale", "description": "Default locale.", "default": "en-us" }, "style": { + "$role": "expression", "type": "string", "enum": [ "None", @@ -39,6 +42,7 @@ "default": "Auto" }, "choiceOptions": { + "$role": "expression", "type": "object", "properties": { "inlineSeparator": { @@ -68,6 +72,7 @@ } }, "confirmChoices": { + "$role": "expression", "type": "array", "items": [ { diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.DateTimeInput.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.DateTimeInput.schema index af8078c864..2c70c1cff8 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.DateTimeInput.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.DateTimeInput.schema @@ -12,6 +12,7 @@ "properties": { "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the datetime output.", "examples": [ @@ -19,6 +20,7 @@ ] }, "defaultLocale": { + "$role": "expression", "type": "string", "title": "Default locale", "description": "Default locale.", diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.InputDialog.json b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.InputDialog.json index 2708963604..c241cadd03 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.InputDialog.json +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.InputDialog.json @@ -9,6 +9,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -48,7 +49,8 @@ ] }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ "integer", "string" ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -59,7 +61,8 @@ "validations": { "type": "array", "items": { - "$role": "expression" + "$role": "expression", + "type": "string" }, "title": "Validation expressions", "description": "Expression to validate user input.", @@ -70,6 +73,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -81,6 +85,7 @@ }, "defaultValue": { "$role": "expression", + "type": [ "object", "array", "number", "integer", "boolean", "string" ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ @@ -90,6 +95,7 @@ }, "value": { "$role": "expression", + "type": [ "object", "array", "number", "integer", "boolean", "string" ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ @@ -97,9 +103,10 @@ ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ "boolean", "string" ], "title": "Always prompt", - "description": "Collect information even if the specified 'property' is not empty.", + "description": "Collect information even if the specified 'property' is not empty.", "default": false, "examples": [ false @@ -107,6 +114,7 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.NumberInput.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.NumberInput.schema index 65903306ee..6d558a2d16 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.NumberInput.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.NumberInput.schema @@ -12,13 +12,16 @@ "properties": { "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the number output.", "examples": [ - "int(this.value)" + "=this.value", + "=int(this.text)" ] }, "defaultLocale": { + "$role": "expression", "type": "string", "title": "Default locale", "description": "Default locale.", diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.OAuthInput.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.OAuthInput.schema index 016adca460..6c7860886d 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.OAuthInput.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.OAuthInput.schema @@ -6,6 +6,7 @@ "type": "object", "properties": { "connectionName": { + "$role": "expression", "type": "string", "title": "Connection name", "description": "The connection name configured in Azure Web App Bot OAuth settings.", @@ -15,6 +16,7 @@ }, "disabled": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ @@ -22,6 +24,7 @@ ] }, "text": { + "$role": "expression", "type": "string", "title": "Text", "description": "Text shown in the OAuth signin card.", @@ -30,6 +33,7 @@ ] }, "title": { + "$role": "expression", "type": "string", "title": "Title", "description": "Title shown in the OAuth signin card.", @@ -38,13 +42,15 @@ ] }, "timeout": { - "type": "integer", + "$role": "expression", + "type": [ "integer", "string" ], "title": "Timeout", "description": "Time out setting for the OAuth signin card.", "default": "900000" }, "property": { "$role": "expression", + "type": "string", "title": "Token property", "description": "Property to store the OAuth token result.", "examples": [ @@ -68,7 +74,8 @@ ] }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ "integer", "string" ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -78,6 +85,7 @@ }, "defaultValue": { "$role": "expression", + "type": [ "object", "array", "number", "integer", "boolean", "string" ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ @@ -86,6 +94,7 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ "boolean", "string" ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.QnAMakerDialog.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.QnAMakerDialog.schema index b63b384776..2cf8fe6815 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.QnAMakerDialog.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.QnAMakerDialog.schema @@ -8,21 +8,24 @@ "properties": { "knowledgeBaseId": { "$role": "expression", + "type": "string", "title": "KnowledgeBase Id", "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", - "default": "settings.qna.knowledgebaseid" + "default": "=settings.qna.knowledgebaseid" }, "endpointKey": { "$role": "expression", + "type": "string", "title": "Endpoint Key", "description": "Endpoint key for the QnA Maker KB.", - "default": "settings.qna.endpointkey" + "default": "=settings.qna.endpointkey" }, "hostname": { "$role": "expression", + "type": "string", "title": "Hostname", "description": "Hostname for your QnA Maker service.", - "default": "settings.qna.hostname", + "default": "=settings.qna.hostname", "examples": [ "https://yourserver.azurewebsites.net/qnamaker" ] @@ -34,18 +37,21 @@ "default": "Sorry, I did not find an answer." }, "threshold": { - "type": "number", + "$role": "expression", + "type": [ "number", "string" ], "title": "Threshold", "description": "Threshold score to filter results.", "default": 0.3 }, "activeLearningCardTitle": { + "$role": "expression", "type": "string", "title": "Active learning card title", "description": "Title for active learning suggestions card.", "default": "Did you mean:" }, "cardNoMatchText": { + "$role": "expression", "type": "string", "title": "Card no match text", "description": "Text for no match option.", @@ -58,7 +64,8 @@ "default": "Thanks for the feedback." }, "strictFilters": { - "type": "array", + "$role": "expression", + "type": [ "array", "string" ], "title": "Strict Filters", "description": "Metadata filters to use when calling the QnA Maker KB.", "items": { @@ -78,7 +85,8 @@ } }, "top": { - "type": "number", + "$role": "expression", + "type": [ "number", "string" ], "title": "Top", "description": "The number of answers you want to retrieve.", "default": 3 @@ -93,6 +101,11 @@ "type": "string", "title": "RankerType", "description": "Type of Ranker.", + "enum": [ + "Default", + "QuestionOnly", + "AutoSuggestQuestion" + ], "default": "Default" } }, diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.TextInput.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.TextInput.schema index aeb2f87116..02ee2c4938 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.TextInput.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Dialogs/Microsoft.TextInput.schema @@ -12,10 +12,12 @@ "properties": { "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the output.", "examples": [ - "toUpper(this.value)" + "=toUpper(this.value)", + "@{toUpper(this.value)}" ] } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Testing/Microsoft.Test.Script.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Testing/Microsoft.Test.Script.schema index a53fb701e7..9e1671db5d 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Testing/Microsoft.Test.Script.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Testing/Microsoft.Test.Script.schema @@ -21,6 +21,12 @@ "$kind": "Microsoft.Test.ITestAction" } }, + "locale": { + "type": "string", + "title": "Locale", + "description": "Set the locale for the user utterances in the script.", + "default": "en-us" + }, "enableTrace": { "type": "boolean", "title": "Enable Trace Activity", diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Selectors/ConditionalSelector.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Selectors/ConditionalSelector.cs index 039d78c695..3e8c8e0a32 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Selectors/ConditionalSelector.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Selectors/ConditionalSelector.cs @@ -21,7 +21,6 @@ public class ConditionalSelector : ITriggerSelector private IReadOnlyList _conditionals; private bool _evaluate; - private Expression condition; /// /// Gets or sets expression that determines which selector to use. @@ -30,11 +29,7 @@ public class ConditionalSelector : ITriggerSelector /// Expression that determines which selector to use. /// [JsonProperty("condition")] - public string Condition - { - get => condition?.ToString(); - set => this.condition = (value != null) ? Parser.Parse(value) : null; - } + public BoolExpression Condition { get; set; } /// /// Gets or sets selector if is true. @@ -69,8 +64,8 @@ public void Initialize(IEnumerable conditionals, bool evaluate = tr public async Task> Select(SequenceContext context, CancellationToken cancel = default) { - var (value, error) = condition.TryEvaluate(context.GetState()); - var eval = error == null && (bool)value; + var dcState = context.GetState(); + var (eval, _) = Condition.TryGetValue(dcState); ITriggerSelector selector; if (eval) { diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/SequenceContext.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/SequenceContext.cs index cea91e2171..6b0adc8598 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/SequenceContext.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/SequenceContext.cs @@ -73,6 +73,8 @@ public void QueueChanges(ActionChangeList changes) /// True if there were any changes to apply. public async Task ApplyChangesAsync(CancellationToken cancellationToken = default(CancellationToken)) { + var dcState = this.GetState(); + // Retrieve queued changes from turn context var changes = this.Changes ?? new List(); @@ -89,7 +91,7 @@ public void QueueChanges(ActionChangeList changes) { foreach (var keyValue in change.Turn) { - this.GetState().SetValue($"turn.{keyValue.Key}", keyValue.Value); + dcState.SetValue($"turn.{keyValue.Key}", keyValue.Value); } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/Actions/AssertCondition.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/Actions/AssertCondition.cs index 6be4db1577..c72a043f92 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/Actions/AssertCondition.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/Actions/AssertCondition.cs @@ -41,11 +41,13 @@ public AssertCondition([CallerFilePath] string path = "", [CallerLineNumber] int public async override Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default) { - var (result, error) = new ExpressionEngine().Parse(Condition).TryEvaluate(dc.GetState()); + var dcState = dc.GetState(); + + var (result, error) = new ExpressionEngine().Parse(Condition).TryEvaluate(dcState); if ((bool)result == false) { var desc = await new TemplateEngineLanguageGenerator() - .Generate(dc.Context, this.Description, dc.GetState()) + .Generate(dc.Context, this.Description, dcState) .ConfigureAwait(false); throw new Exception(desc); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/MockLuis/MockLuisRecognizer.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/MockLuis/MockLuisRecognizer.cs index ab14f04eeb..7cd0da05c1 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/MockLuis/MockLuisRecognizer.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/MockLuis/MockLuisRecognizer.cs @@ -27,7 +27,6 @@ public class MockLuisRecognizer : Recognizer /// /// Initializes a new instance of the class. /// - /// LUIS application information. /// Where the settings file generated by lubuild is found. /// Name of the LUIS model. /// LUIS options. diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/TestActions/AssertReplyActivity.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/TestActions/AssertReplyActivity.cs index 6b72983ffa..e17c957222 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/TestActions/AssertReplyActivity.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/TestActions/AssertReplyActivity.cs @@ -63,8 +63,8 @@ public virtual void ValidateReply(Activity activity) var engine = new ExpressionEngine(); foreach (var assertion in this.Assertions) { - var (result, error) = engine.Parse(assertion).TryEvaluate(activity); - if ((bool)result != true) + var (result, error) = engine.Parse(assertion).TryEvaluate(activity); + if (result != true) { throw new Exception($"{this.Description} {assertion} {activity}"); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/TestScript.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/TestScript.cs index 29a44d1cac..76edd605ab 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/TestScript.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Testing/TestScript.cs @@ -123,7 +123,7 @@ public async Task ExecuteAsync([CallerMemberName] string testName = null, Resour .UseAdaptiveDialogs() .UseLanguageGeneration(resourceExplorer) .UseMockLuis() - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); adapter.OnTurnError += (context, err) => context.SendActivityAsync(err.Message); } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/TriggerConditions/OnCondition.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/TriggerConditions/OnCondition.cs index 58b1546e42..745ae32604 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/TriggerConditions/OnCondition.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/TriggerConditions/OnCondition.cs @@ -10,7 +10,6 @@ using Microsoft.Bot.Builder.Dialogs.Adaptive.Actions; using Microsoft.Bot.Builder.Dialogs.Debugging; using Microsoft.Bot.Builder.Dialogs.Memory; -using Microsoft.Bot.Builder.Dialogs.Memory.Scopes; using Microsoft.Bot.Expressions; using Microsoft.Bot.Expressions.TriggerTrees; using Newtonsoft.Json; @@ -31,19 +30,18 @@ public class OnCondition : IItemIdentity, IDialogDependencies // constraints from Rule.AddConstraint() private List extraConstraints = new List(); - private string priorityString = null; - // cached expression representing all constraints (constraint AND extraConstraints AND childrenConstraints) private Expression fullConstraint = null; - // cached expression of parsed priority - private Expression priorityExpression = null; - [JsonConstructor] public OnCondition(string condition = null, List actions = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0) { this.RegisterSourceLocation(callerPath, callerLine); - this.Condition = condition; + if (condition != null) + { + this.Condition = condition; + } + this.Actions = actions; } @@ -54,7 +52,7 @@ public OnCondition(string condition = null, List actions = null, [Caller /// The condition which needs to be met for the actions to be executed. /// [JsonProperty("condition")] - public string Condition { get; set; } + public BoolExpression Condition { get; set; } /// /// Gets or sets the actions to add to the plan when the rule constraints are met. @@ -73,15 +71,7 @@ public OnCondition(string condition = null, List actions = null, [Caller /// /// Priority of condition expression. [JsonProperty("priority")] - public string Priority - { - get => priorityString; - set - { - priorityExpression = null; - priorityString = value; - } - } + public IntExpression Priority { get; set; } = new IntExpression(); /// /// Gets or sets a value indicating whether rule should only run once per unique set of memory paths. @@ -122,16 +112,10 @@ public virtual Expression GetExpression(IExpressionParser parser) if (this.fullConstraint == null) { var allExpressions = new List(); - if (!string.IsNullOrWhiteSpace(this.Condition)) + + if (this.Condition != null) { - try - { - allExpressions.Add(parser.Parse(this.Condition)); - } - catch (Exception e) - { - throw new Exception($"Invalid constraint expression: {this.Condition}, {e.Message}"); - } + allExpressions.Add(this.Condition.ToExpression()); } if (this.extraConstraints.Any()) @@ -169,11 +153,6 @@ public virtual Expression GetExpression(IExpressionParser parser) BuiltInFunctions.ValidateUnary)))); } } - - if (priorityExpression == null) - { - priorityExpression = parser.Parse(Priority); - } } return this.fullConstraint; @@ -186,13 +165,13 @@ public virtual Expression GetExpression(IExpressionParser parser) /// Computed priority. public int CurrentPriority(SequenceContext context) { - var (priority, error) = priorityExpression.TryEvaluate(context.GetState()); - if (error != null || !(priority is int)) + var (priority, error) = this.Priority.TryGetValue(context.GetState()); + if (error != null) { priority = -1; } - return (int)priority; + return priority; } /// @@ -207,7 +186,7 @@ public void AddExternalCondition(string condition) { lock (this.extraConstraints) { - this.extraConstraints.Add(new ExpressionEngine().Parse(condition)); + this.extraConstraints.Add(new ExpressionEngine().Parse(condition.TrimStart('='))); this.fullConstraint = null; // reset to force it to be recalcaulated } } @@ -227,8 +206,9 @@ public virtual async Task> ExecuteAsync(SequenceContext p { if (RunOnce) { - var count = planningContext.GetState().GetValue(DialogPath.EventCounter); - planningContext.GetState().SetValue($"{AdaptiveDialog.ConditionTracker}.{Id}.lastRun", count); + var dcState = planningContext.GetState(); + var count = dcState.GetValue(DialogPath.EventCounter); + dcState.SetValue($"{AdaptiveDialog.ConditionTracker}.{Id}.lastRun", count); } return await Task.FromResult(new List() diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/TriggerConditions/OnIntent.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/TriggerConditions/OnIntent.cs index 3f20b2ec22..7ff7252345 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/TriggerConditions/OnIntent.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/TriggerConditions/OnIntent.cs @@ -86,7 +86,8 @@ public override Expression GetExpression(IExpressionParser factory) protected override ActionChangeList OnCreateChangeList(SequenceContext planning, object dialogOptions = null) { - var recognizerResult = planning.GetState().GetValue($"{TurnPath.DIALOGEVENT}.value"); + var dcState = planning.GetState(); + var recognizerResult = dcState.GetValue($"{TurnPath.DIALOGEVENT}.value"); if (recognizerResult != null) { var (name, score) = recognizerResult.GetTopScoringIntent(); diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Converters/ExpressionConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Converters/ExpressionConverter.cs deleted file mode 100644 index 94c3f4da84..0000000000 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Converters/ExpressionConverter.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using Microsoft.Bot.Expressions; -using Newtonsoft.Json; - -namespace Microsoft.Bot.Builder.Dialogs.Declarative.Converters -{ - /// - /// "string" => Expression object converter. - /// - public class ExpressionConverter : JsonConverter - { - public override bool CanRead => true; - - public override bool CanConvert(Type objectType) - { - return objectType == typeof(Expression); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.ValueType == typeof(string)) - { - return new ExpressionEngine().Parse((string)reader.Value); - } - - throw new JsonSerializationException("Expected string expression."); - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - value = ((Expression)value).ToString(); - serializer.Serialize(writer, value); - } - } -} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Converters/ExpressionPropertyConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Converters/ExpressionPropertyConverter.cs deleted file mode 100644 index bda255d103..0000000000 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Converters/ExpressionPropertyConverter.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using Microsoft.Bot.Expressions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace Microsoft.Bot.Builder.Dialogs.Declarative.Converters -{ - /// - /// Converter which allows json to be expression to object or static object. - /// - /// The property type to construct which is IExpressionProperty. - public class ExpressionPropertyConverter : JsonConverter - where T : IExpressionProperty, new() - { - public override bool CanRead => true; - - public override bool CanConvert(Type objectType) - { - return typeof(T) == objectType; - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.ValueType == typeof(string)) - { - var prop = new T(); - prop.SetValue((string)reader.Value); - return prop; - } - else - { - var prop = new T(); - prop.SetValue(JToken.Load(reader)); - return prop; - } - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - serializer.Serialize(writer, value); - } - } -} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/DialogComponentRegistration.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/DialogComponentRegistration.cs index 9177d38b34..db8e87d36c 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/DialogComponentRegistration.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/DialogComponentRegistration.cs @@ -14,7 +14,6 @@ public override IEnumerable GetConverters(ISourceMap sourceMap, I yield return new InterfaceConverter(refResolver, sourceMap, paths); yield return new InterfaceConverter(refResolver, sourceMap, paths); yield return new InterfaceConverter(refResolver, sourceMap, paths); - yield return new ExpressionConverter(); yield return new ActivityConverter(); } } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/ExpressionProperty.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/ExpressionProperty.cs deleted file mode 100644 index 9118ae4f94..0000000000 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/ExpressionProperty.cs +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.Bot.Expressions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace Microsoft.Bot.Builder.Dialogs.Declarative -{ - /// - /// Defines a Expression or value for a property. - /// - /// type of object the expression should evaluate to. - public class ExpressionProperty : IExpressionProperty - { - public ExpressionProperty() - { - } - - public ExpressionProperty(string expression) - { - this.Expression = expression; - } - - public ExpressionProperty(object value) - { - SetValue(value); - } - - public ExpressionProperty(T value) - { - this.Value = value; - } - - /// - /// Gets or sets expression to use to get the value from data. - /// - /// - /// Expression to use to get the value from data. - /// - [JsonProperty("expression")] - public string Expression - { - get { return InnerExpression?.ToString(); } - set { InnerExpression = new ExpressionEngine().Parse(value); } - } - - /// - /// Gets or sets static value to use for the result (instead of data binding). - /// - /// - /// Static value to use for the result (instead of data binding). - /// - [JsonProperty("value")] - public T Value { get; set; } - - protected Expression InnerExpression { get; set; } - - /// - /// Set the value. - /// - /// value to set. - public virtual void SetValue(object value) - { - if (value is string expression) - { - this.Expression = expression; - } - else if (value is JObject job) - { - dynamic jobj = job; - if (jobj.value != null) - { - this.Value = ConvertObject(jobj.value); - } - else if (jobj.expression != null) - { - this.Expression = jobj.expression.ToString(); - } - else - { - this.Value = ConvertObject(job); - } - } - else if (value is JArray jar) - { - this.Value = ConvertObject(jar); - } - } - - /// - /// Get the value. - /// - /// data to use for expression binding. - /// value. - public virtual T GetValue(object data) - { - if (Value != null) - { - return Value; - } - - var (result, error) = InnerExpression.TryEvaluate(data); - if (error != null) - { - return default(T); - } - - return ConvertObject(result); - } - - /// - /// Convert raw object to desired value type. - /// - /// - /// This method is called whenever an object is fetched via expression or is deserialized from raw text. - /// - /// result to convert to object of type T. - /// object of type T. - protected virtual T ConvertObject(object result) - { - if (result is T) - { - return (T)result; - } - - return JToken.FromObject(result).ToObject(); - } - } -} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/IExpressionProperty.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/IExpressionProperty.cs deleted file mode 100644 index 2ef7348a7f..0000000000 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/IExpressionProperty.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Microsoft.Bot.Builder.Dialogs.Declarative -{ - public interface IExpressionProperty - { - void SetValue(object value); - } -} diff --git a/libraries/Microsoft.Bot.Builder.Dialogs/Prompts/DatetimePrompt.cs b/libraries/Microsoft.Bot.Builder.Dialogs/Prompts/DatetimePrompt.cs index 8d6185db7a..588baa3137 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs/Prompts/DatetimePrompt.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs/Prompts/DatetimePrompt.cs @@ -100,7 +100,8 @@ public DateTimePrompt(string dialogId, PromptValidator { var message = turnContext.Activity.AsMessageActivity(); var culture = turnContext.Activity.Locale ?? DefaultLocale ?? English; - var results = DateTimeRecognizer.RecognizeDateTime(message.Text, culture); + var refTime = turnContext.Activity.LocalTimestamp?.LocalDateTime; + var results = DateTimeRecognizer.RecognizeDateTime(message.Text, culture, refTime: refTime); if (results.Count > 0) { // Return list of resolutions from first match diff --git a/libraries/Microsoft.Bot.Builder/Adapters/TestAdapter.cs b/libraries/Microsoft.Bot.Builder/Adapters/TestAdapter.cs index e3caa4dd14..f09824f218 100644 --- a/libraries/Microsoft.Bot.Builder/Adapters/TestAdapter.cs +++ b/libraries/Microsoft.Bot.Builder/Adapters/TestAdapter.cs @@ -172,7 +172,12 @@ public async Task ProcessActivityAsync(Activity activity, BotCallbackHandler cal if (activity.Timestamp == null || activity.Timestamp == default(DateTimeOffset)) { - activity.Timestamp = DateTime.UtcNow; + activity.Timestamp = DateTimeOffset.UtcNow; + } + + if (activity.LocalTimestamp == null || activity.LocalTimestamp == default(DateTimeOffset)) + { + activity.LocalTimestamp = DateTimeOffset.Now; } using (var context = new TurnContext(this, activity)) diff --git a/libraries/Microsoft.Bot.Builder/TraceTranscriptLogger.cs b/libraries/Microsoft.Bot.Builder/TraceTranscriptLogger.cs index 3ba6d42938..c2c8bbfb67 100644 --- a/libraries/Microsoft.Bot.Builder/TraceTranscriptLogger.cs +++ b/libraries/Microsoft.Bot.Builder/TraceTranscriptLogger.cs @@ -15,6 +15,18 @@ public class TraceTranscriptLogger : ITranscriptLogger { private static JsonSerializerSettings serializationSettings = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented }; + private bool traceActivity; + + public TraceTranscriptLogger() + : this(true) + { + } + + public TraceTranscriptLogger(bool traceActivity) + { + this.traceActivity = traceActivity; + } + /// /// Log an activity to the transcript. /// @@ -23,7 +35,22 @@ public class TraceTranscriptLogger : ITranscriptLogger public Task LogActivityAsync(IActivity activity) { BotAssert.ActivityNotNull(activity); - Trace.TraceInformation(JsonConvert.SerializeObject(activity, serializationSettings)); + if (traceActivity) + { + Trace.TraceInformation(JsonConvert.SerializeObject(activity, serializationSettings)); + } + else + { + if (Debugger.IsAttached && activity.Type == ActivityTypes.Message) + { + Trace.TraceInformation($"{activity.From.Name ?? activity.From.Id ?? activity.From.Role} [{activity.Type}] {activity.AsMessageActivity()?.Text}"); + } + else + { + Trace.TraceInformation($"{activity.From.Name ?? activity.From.Id ?? activity.From.Role} [{activity.Type}]"); + } + } + return Task.CompletedTask; } } diff --git a/libraries/Microsoft.Bot.Expressions/BuiltInFunctions.cs b/libraries/Microsoft.Bot.Expressions/BuiltInFunctions.cs index 35154ea27c..552575fc07 100644 --- a/libraries/Microsoft.Bot.Expressions/BuiltInFunctions.cs +++ b/libraries/Microsoft.Bot.Expressions/BuiltInFunctions.cs @@ -1286,33 +1286,29 @@ private static (object value, string error) If(Expression expression, IMemory st private static (object value, string error) Substring(Expression expression, IMemory state) { - object result = null; + string result = null; string error; - dynamic str; - (str, error) = expression.Children[0].TryEvaluate(state); + string str; + (str, error) = expression.Children[0].TryEvaluate(state); if (error == null) { if (str == null) { result = string.Empty; } - else if (str is string) + else { - dynamic start; + int start; var startExpr = expression.Children[1]; - (start, error) = startExpr.TryEvaluate(state); - if (error == null && !(start is int)) - { - error = $"{startExpr} is not an integer."; - } - else if (start < 0 || start >= str.Length) + (start, error) = startExpr.TryEvaluate(state); + if (error == null && (start < 0 || start >= str.Length)) { error = $"{startExpr}={start} which is out of range for {str}."; } if (error == null) { - dynamic length; + int length; if (expression.Children.Length == 2) { // Without length, compute to end @@ -1321,12 +1317,8 @@ private static (object value, string error) Substring(Expression expression, IMe else { var lengthExpr = expression.Children[2]; - (length, error) = lengthExpr.TryEvaluate(state); - if (error == null && !(length is int)) - { - error = $"{lengthExpr} is not an integer."; - } - else if (length < 0 || start + length > str.Length) + (length, error) = lengthExpr.TryEvaluate(state); + if (error == null && (length < 0 || start + length > str.Length)) { error = $"{lengthExpr}={length} which is out of range for {str}."; } @@ -1338,10 +1330,6 @@ private static (object value, string error) Substring(Expression expression, IMe } } } - else - { - error = $"{expression.Children[0]} is not a string."; - } } return (result, error); @@ -1447,10 +1435,10 @@ private static (object value, string error) Where(Expression expression, IMemory // the local iterator is pushed as one memory layer in the memory stack stackedMemory.Push(SimpleObjectMemory.Wrap(local)); - (var r, _) = expression.Children[2].TryEvaluate(stackedMemory); + var (r, _) = expression.Children[2].TryEvaluate(stackedMemory); stackedMemory.Pop(); - if ((bool)r) + if (r) { // add if only if it evaluates to true ((List)result).Add(local[iteratorName]); @@ -2152,29 +2140,17 @@ private static (object value, string error) Skip(Expression expression, object s { if (TryParseList(arr, out var list)) { - object start; - var startInt = 0; + int start = 0; var startExpr = expression.Children[1]; - (start, error) = startExpr.TryEvaluate(state); - if (error == null) + (start, error) = startExpr.TryEvaluate(state); + if (error == null && (start < 0 || start >= list.Count)) { - if (start == null || !start.IsInteger()) - { - error = $"{startExpr} is not an integer."; - } - else - { - startInt = (int)start; - if (startInt < 0 || startInt >= list.Count) - { - error = $"{startExpr}={start} which is out of range for {arr}"; - } - } + error = $"{startExpr}={start} which is out of range for {arr}"; + } - if (error == null) - { - result = list.OfType().Skip(startInt).ToList(); - } + if (error == null) + { + result = list.OfType().Skip(start).ToList(); } } else @@ -2198,39 +2174,31 @@ private static (object, string) Take(Expression expression, object state) var arrIsStr = arr.GetType() == typeof(string); if (arrIsList || arrIsStr) { - object countObj; + int count; var countExpr = expression.Children[1]; - (countObj, error) = countExpr.TryEvaluate(state); + (count, error) = countExpr.TryEvaluate(state); if (error == null) { - if (countObj == null || !countObj.IsInteger()) + if (arrIsList) { - error = $"{countExpr} is not an integer."; + if (count < 0 || count >= list.Count) + { + error = $"{countExpr}={count} which is out of range for {arr}"; + } + else + { + result = list.OfType().Take(count).ToList(); + } } else { - var count = (int)countObj; - if (arrIsList) + if (count < 0 || count > list.Count) { - if (count < 0 || count >= list.Count) - { - error = $"{countExpr}={count} which is out of range for {arr}"; - } - else - { - result = list.OfType().Take(count).ToList(); - } + error = $"{countExpr}={count} which is out of range for {arr}"; } else { - if (count < 0 || count > list.Count) - { - error = $"{countExpr}={count} which is out of range for {arr}"; - } - else - { - result = arr.ToString().Substring(0, count); - } + result = arr.ToString().Substring(0, count); } } } @@ -2256,20 +2224,10 @@ private static (object, string) SubArray(Expression expression, object state) if (TryParseList(arr, out var list)) { var startExpr = expression.Children[1]; - object startObj; - (startObj, error) = startExpr.TryEvaluate(state); - var start = 0; + int start; + (start, error) = startExpr.TryEvaluate(state); if (error == null) { - if (startObj == null || !startObj.IsInteger()) - { - error = $"{startExpr} is not an integer."; - } - else - { - start = (int)startObj; - } - if (error == null && (start < 0 || start > list.Count)) { error = $"{startExpr}={start} which is out of range for {arr}"; @@ -2277,7 +2235,7 @@ private static (object, string) SubArray(Expression expression, object state) if (error == null) { - var end = 0; + int end = 0; if (expression.Children.Length == 2) { end = list.Count; @@ -2285,23 +2243,10 @@ private static (object, string) SubArray(Expression expression, object state) else { var endExpr = expression.Children[2]; - object endObj; - (endObj, error) = endExpr.TryEvaluate(state); - if (error == null) + (end, error) = endExpr.TryEvaluate(state); + if (error == null && (end < 0 || end > list.Count)) { - if (endObj == null || !endObj.IsInteger()) - { - error = $"{endExpr} is not an integer."; - } - else - { - end = (int)endObj; - } - - if (error == null && (end < 0 || end > list.Count)) - { - error = $"{endExpr}={end} which is out of range for {arr}"; - } + error = $"{endExpr}={end} which is out of range for {arr}"; } } @@ -2348,19 +2293,18 @@ private static EvaluateExpressionDelegate SortBy(bool isDescending) { var jarray = JArray.FromObject(list.OfType().ToList()); var propertyNameExpression = expression.Children[1]; - object propertyName; - (propertyName, error) = propertyNameExpression.TryEvaluate(state); - var propertyNameString = string.Empty; + string propertyName; + (propertyName, error) = propertyNameExpression.TryEvaluate(state); if (error == null) { - propertyNameString = propertyName == null ? string.Empty : propertyName.ToString(); + propertyName = propertyName ?? string.Empty; if (isDescending) { - result = jarray.OrderByDescending(obj => obj[propertyNameString]).ToList(); + result = jarray.OrderByDescending(obj => obj[propertyName]).ToList(); } else { - result = jarray.OrderBy(obj => obj[propertyNameString]).ToList(); + result = jarray.OrderBy(obj => obj[propertyName]).ToList(); } } } diff --git a/libraries/Microsoft.Bot.Expressions/Expression.cs b/libraries/Microsoft.Bot.Expressions/Expression.cs index 054b5c853a..103eea03aa 100644 --- a/libraries/Microsoft.Bot.Expressions/Expression.cs +++ b/libraries/Microsoft.Bot.Expressions/Expression.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using Microsoft.Bot.Expressions.Memory; +using Newtonsoft.Json; namespace Microsoft.Bot.Expressions { @@ -268,10 +269,137 @@ public void ValidateTree() /// /// Computed value and an error string. If the string is non-null, then there was an evaluation error. public (object value, string error) TryEvaluate(object state) - => Evaluator.TryEvaluate(this, SimpleObjectMemory.Wrap(state)); + => this.TryEvaluate(state); + /// + /// Evaluate the expression. + /// + /// + /// Global state to evaluate accessor expressions against. Can be , + /// otherwise reflection is used to access property and then indexer. + /// + /// Computed value and an error string. If the string is non-null, then there was an evaluation error. public (object value, string error) TryEvaluate(IMemory state) - => Evaluator.TryEvaluate(this, state); + => this.TryEvaluate(state); + + /// + /// Evaluate the expression. + /// + /// type of result of the expression. + /// + /// Global state to evaluate accessor expressions against. Can be , + /// otherwise reflection is used to access property and then indexer. + /// + /// Computed value and an error string. If the string is non-null, then there was an evaluation error. + public (T value, string error) TryEvaluate(object state) + => this.TryEvaluate(SimpleObjectMemory.Wrap(state)); + + /// + /// Evaluate the expression. + /// + /// type of result of the expression. + /// + /// Global state to evaluate accessor expressions against. Can be , + /// otherwise reflection is used to access property and then indexer. + /// + /// Computed value and an error string. If the string is non-null, then there was an evaluation error. + public (T value, string error) TryEvaluate(IMemory state) + { + var (result, error) = Evaluator.TryEvaluate(this, state); + if (error != null) + { + return (default(T), error); + } + + if (result is T) + { + return ((T)result, error); + } + + try + { + if (typeof(T) == typeof(object)) + { + if (result == null) + { + return (default(T), error); + } + + return ((T)result, error); + } + + if (typeof(T) == typeof(string)) + { + if (result == null) + { + return (default(T), null); + } + + return ((T)(object)result.ToString(), error); + } + + if (typeof(T) == typeof(bool)) + { + return ((T)(object)Convert.ToBoolean(result), error); + } + + if (typeof(T) == typeof(byte)) + { + return ((T)(object)Convert.ToByte(result), (Convert.ToByte(result) == Convert.ToDouble(result)) ? null : Error(result)); + } + + if (typeof(T) == typeof(short)) + { + return ((T)(object)Convert.ToInt16(result), (Convert.ToInt16(result) == Convert.ToDouble(result)) ? null : Error(result)); + } + + if (typeof(T) == typeof(int)) + { + return ((T)(object)Convert.ToInt32(result), (Convert.ToInt32(result) == Convert.ToDouble(result)) ? null : Error(result)); + } + + if (typeof(T) == typeof(long)) + { + return ((T)(object)Convert.ToInt64(result), (Convert.ToInt64(result) == Convert.ToDouble(result)) ? null : Error(result)); + } + + if (typeof(T) == typeof(ushort)) + { + return ((T)(object)Convert.ToUInt16(result), (Convert.ToUInt16(result) == Convert.ToDouble(result)) ? null : Error(result)); + } + + if (typeof(T) == typeof(uint)) + { + return ((T)(object)Convert.ToUInt32(result), (Convert.ToUInt32(result) == Convert.ToDouble(result)) ? null : Error(result)); + } + + if (typeof(T) == typeof(ulong)) + { + return ((T)(object)Convert.ToUInt64(result), (Convert.ToUInt64(result) == Convert.ToDouble(result)) ? null : Error(result)); + } + + if (typeof(T) == typeof(float)) + { + return ((T)(object)Convert.ToSingle(Convert.ToDecimal(result)), null); + } + + if (typeof(T) == typeof(double)) + { + return ((T)(object)Convert.ToDouble(Convert.ToDecimal(result)), null); + } + + if (result == null) + { + return (default(T), error); + } + + return (JsonConvert.DeserializeObject(JsonConvert.SerializeObject(result)), null); + } + catch + { + return (default(T), Error(result)); + } + } public override string ToString() { @@ -348,5 +476,10 @@ public override string ToString() return builder.ToString(); } + + private string Error(object result) + { + return $"'{result}' is not of type {typeof(T).Name}"; + } } } diff --git a/libraries/Microsoft.Bot.Expressions/TriggerTrees/Clause.cs b/libraries/Microsoft.Bot.Expressions/TriggerTrees/Clause.cs index 7f7a5f42d4..503e8f0d11 100644 --- a/libraries/Microsoft.Bot.Expressions/TriggerTrees/Clause.cs +++ b/libraries/Microsoft.Bot.Expressions/TriggerTrees/Clause.cs @@ -193,8 +193,8 @@ public bool Matches(Clause clause, object memory) matched = true; if (ignored != null) { - var (value, err) = ignored.TryEvaluate(memory); - matched = err == null && value is bool match && match; + var (match, err) = ignored.TryEvaluate(memory); + matched = err == null && match; } } diff --git a/libraries/Microsoft.Bot.Expressions/TriggerTrees/Node.cs b/libraries/Microsoft.Bot.Expressions/TriggerTrees/Node.cs index 71e2c65e19..7962dff64b 100644 --- a/libraries/Microsoft.Bot.Expressions/TriggerTrees/Node.cs +++ b/libraries/Microsoft.Bot.Expressions/TriggerTrees/Node.cs @@ -599,8 +599,8 @@ private bool Matches(object state, HashSet matches, Dictionary(state); + if (error == null && match) { foreach (var trigger in Triggers) { diff --git a/libraries/Microsoft.Bot.Schema/ActivityEx.cs b/libraries/Microsoft.Bot.Schema/ActivityEx.cs index f713543dfb..c26978ca76 100644 --- a/libraries/Microsoft.Bot.Schema/ActivityEx.cs +++ b/libraries/Microsoft.Bot.Schema/ActivityEx.cs @@ -196,11 +196,11 @@ public ITraceActivity CreateTrace(string name, object value = null, string value Type = ActivityTypes.Trace, Timestamp = DateTime.UtcNow, From = new ChannelAccount(id: this.Recipient?.Id, name: this.Recipient?.Name), - Recipient = new ChannelAccount(id: this.From.Id, name: this.From.Name), + Recipient = new ChannelAccount(id: this.From?.Id, name: this.From?.Name), ReplyToId = this.Id, ServiceUrl = this.ServiceUrl, ChannelId = this.ChannelId, - Conversation = new ConversationAccount(isGroup: this.Conversation.IsGroup, id: this.Conversation.Id, name: this.Conversation.Name), + Conversation = this.Conversation, Name = name, Label = label, ValueType = valueType ?? value?.GetType().Name, diff --git a/schemas/baseComponent.schema b/schemas/baseComponent.schema index 60df6dcd14..5ca579661b 100644 --- a/schemas/baseComponent.schema +++ b/schemas/baseComponent.schema @@ -33,10 +33,6 @@ "type": "object", "description": "Extra information for the Bot Framework Designer." }, - "expression": { - "type": "string", - "description": "String must contain an expression." - }, "lg": { "type": "string", "description": "String is used for language generation." @@ -45,6 +41,18 @@ "type": "string", "description": "String must contain a memory path.", "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$" + }, + "boolExpression": { + "type": [ "boolean", "string"] + }, + "integerExpression": { + "type": [ "integer", "string" ] + }, + "numberExpression": { + "type": [ "number", "string" ] + }, + "valueExpression": { + "type": [ "object", "array", "number", "integer", "boolean", "string"] } }, "properties": { diff --git a/schemas/readme.md b/schemas/readme.md index afb7728584..16c55979ef 100644 --- a/schemas/readme.md +++ b/schemas/readme.md @@ -11,6 +11,4 @@ There are two tools here: This will update all of the .schema files and make them accessible through urls like: * __component.schema__: `https://raw.githubusercontent.com/Microsoft/botbuilder-dotnet/{branch}/schemas/component.schema` - * __sdk.shema__: `https://raw.githubusercontent.com/Microsoft/botbuilder-dotnet/{branch}/schemas/sdk.schema` - - \ No newline at end of file + * __sdk.shema__: `https://raw.githubusercontent.com/Microsoft/botbuilder-dotnet/{branch}/schemas/sdk.schema` \ No newline at end of file diff --git a/schemas/sdk.schema b/schemas/sdk.schema index e8ef017a54..80f50375a9 100644 --- a/schemas/sdk.schema +++ b/schemas/sdk.schema @@ -880,12 +880,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "activity": { "$kind": "Microsoft.IActivityTemplate", @@ -894,6 +897,9 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "expectedProperties": { + "$role": "expression", + "title": "Expected Properties", + "description": "Properties expected to be filled by entities from the user", "oneOf": [ { "type": "array", @@ -901,14 +907,14 @@ "type": "string", "title": "string" }, - "title": "array", - "description": "Properties expected to be filled by entities from the user" + "title": "array" }, { "type": "string", "title": "string" } - ] + ], + "type": "string" } }, "additionalProperties": false, @@ -969,12 +975,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "prompt": { "$kind": "Microsoft.IActivityTemplate", @@ -1013,7 +1022,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -1037,6 +1050,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -1044,30 +1058,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -1077,15 +1108,19 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { + "$role": "expression", "type": "string", "enum": [ "all", @@ -1154,15 +1189,23 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "dialog": { "$kind": "Microsoft.IDialog", + "$role": "expression", + "type": [ + "string", + "object" + ], "title": "Dialog name", "description": "Name of the dialog to call.", "examples": [ @@ -1171,7 +1214,11 @@ "$ref": "#/definitions/Microsoft.IDialog" }, "options": { - "type": "object", + "$role": "expression", + "type": [ + "string", + "object" + ], "title": "Options", "description": "One or more options that are passed to the dialog that is called.", "additionalProperties": { @@ -1180,19 +1227,23 @@ } }, "activityProcessed": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Activity Processed", "description": "When set to false, the dialog that is called can process the current activity.", "default": true }, "resultProperty": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store any value returned by the dialog that is called.", "examples": [ "dialog.userName" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -1253,12 +1304,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -1319,20 +1373,32 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "eventName": { + "$role": "expression", + "type": "string", "title": "Event name", - "description": "Name of the event to emit.", - "type": "string" + "description": "Name of the event to emit." }, "eventValue": { - "type": "object", + "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Event value", "description": "Value to emit with the event (optional).", "additionalProperties": true @@ -1396,12 +1462,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "prompt": { "$kind": "Microsoft.IActivityTemplate", @@ -1440,7 +1509,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -1464,6 +1537,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -1471,30 +1545,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -1504,15 +1595,19 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { + "$role": "expression", "type": "string", "enum": [ "value", @@ -1767,12 +1862,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "prompt": { "$kind": "Microsoft.IActivityTemplate", @@ -1811,7 +1909,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -1835,6 +1937,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -1842,30 +1945,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -1875,30 +1995,35 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the confirm output.", "examples": [ "concat('confirmation:', this.value)" - ], - "type": "string" + ] }, "defaultLocale": { + "$role": "expression", "type": "string", "title": "Default locale", "description": "Default locale.", "default": "en-us" }, "style": { + "$role": "expression", "type": "string", "enum": [ "None", @@ -1913,6 +2038,7 @@ "default": "Auto" }, "choiceOptions": { + "$role": "expression", "type": "object", "properties": { "inlineSeparator": { @@ -1939,9 +2065,11 @@ "description": "If true, inline and list style choices will be prefixed with the index of the choice.", "default": true } - } + }, + "description": "String must contain an expression." }, "confirmChoices": { + "$role": "expression", "type": "array", "items": [ { @@ -1967,7 +2095,8 @@ } } } - ] + ], + "description": "String must contain an expression." } }, "additionalProperties": false, @@ -2080,12 +2209,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -2317,12 +2449,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "prompt": { "$kind": "Microsoft.IActivityTemplate", @@ -2361,7 +2496,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -2385,6 +2524,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -2392,30 +2532,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -2425,24 +2582,28 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the datetime output.", "examples": [ "this.value[0].Value" - ], - "type": "string" + ] }, "defaultLocale": { + "$role": "expression", "type": "string", "title": "Default locale", "description": "Default locale.", @@ -2507,12 +2668,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -2573,21 +2737,24 @@ }, "activityId": { "$role": "expression", + "type": "string", "title": "ActivityId", "description": "expression to an activityId to delete", "examples": [ - "$lastActivity" - ], - "type": "string" + "=$lastActivity" + ] }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -2650,12 +2817,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "properties": { "type": "array", @@ -2663,9 +2833,9 @@ "description": "Properties to delete.", "items": { "$role": "expression", + "type": "string", "title": "Property", - "description": "Property to delete.", - "type": "string" + "description": "Property to delete." } } }, @@ -2728,18 +2898,21 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "property": { "$role": "expression", + "type": "string", "title": "Property", - "description": "Property to delete.", - "type": "string" + "description": "Property to delete." } }, "additionalProperties": false, @@ -2853,14 +3026,18 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "changeType": { + "$role": "expression", "type": "string", "title": "Type of change", "description": "Type of change to apply to the current actions.", @@ -2941,6 +3118,7 @@ "description": "Optional id for the dialog" }, "changeType": { + "$role": "expression", "type": "string", "title": "Type of change", "description": "Type of change to the array in memory.", @@ -2954,35 +3132,45 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "itemsProperty": { "$role": "expression", + "type": "string", "title": "Items property", - "description": "Property that holds the array to update.", - "type": "string" + "description": "Property that holds the array to update." }, "resultProperty": { "$role": "expression", + "type": "string", "title": "Result Property", - "description": "Property to store the result of this action.", - "type": "string" + "description": "Property to store the result of this action." }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "New value or expression.", "examples": [ "'milk'", "dialog.favColor", "dialog.favColor == 'red'" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -3097,46 +3285,55 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "eventName": { + "$role": "expression", + "type": "string", "title": "Event name", "description": "Name of the event to emit.", - "anyOf": [ - { - "enum": [ - "beginDialog", - "resumeDialog", - "repromptDialog", - "cancelDialog", - "endDialog", - "activityReceived", - "recognizedIntent", - "unknownIntent", - "actionsStarted", - "actionsSaved", - "actionsEnded", - "actionsResumed" - ] - }, - { - "type": "string" - } + "enum": [ + "beginDialog", + "resumeDialog", + "repromptDialog", + "cancelDialog", + "endDialog", + "activityReceived", + "recognizedIntent", + "unknownIntent", + "actionsStarted", + "actionsSaved", + "actionsEnded", + "actionsResumed" ] }, "eventValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Event value", - "description": "Value to emit with the event (optional).", - "type": "string" + "description": "Value to emit with the event (optional)." }, "bubbleEvent": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Bubble event", "description": "If true this event is passed on to parent dialogs.", "default": false @@ -3201,22 +3398,32 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Result value returned to the parent dialog.", "examples": [ - "dialog.userName", - "'tomato'" - ], - "type": "string" + "=dialog.userName", + "='tomato'" + ] } }, "additionalProperties": false, @@ -3277,12 +3484,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -3493,21 +3703,26 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "itemsProperty": { "$role": "expression", + "type": [ + "string" + ], "title": "Items property", "description": "Property that holds the array.", "examples": [ "user.todoList" - ], - "type": "string" + ] }, "actions": { "type": "array", @@ -3579,21 +3794,24 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "itemsProperty": { "$role": "expression", + "type": "string", "title": "Items property", "description": "Property that holds the array.", "examples": [ "user.todoList" - ], - "type": "string" + ] }, "actions": { "type": "array", @@ -3605,7 +3823,11 @@ } }, "pageSize": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Page size", "description": "Number of items in each page.", "default": 10 @@ -3671,21 +3893,24 @@ }, "activityId": { "$role": "expression", + "type": "string", "title": "ActivityId", "description": "expression to an activityId to get the members. If none is defined then the current activity id will be used.", "examples": [ "$lastActivity" - ], - "type": "string" + ] }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -3746,12 +3971,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -3812,14 +4040,18 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "actionId": { + "$role": "expression", "type": "string", "title": "Action Id", "description": "Action Id to execute next" @@ -3988,12 +4220,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "method": { "type": "string", @@ -4012,6 +4247,7 @@ ] }, "url": { + "$role": "expression", "type": "string", "title": "Url", "description": "URL to call (supports data binding).", @@ -4020,27 +4256,40 @@ ] }, "body": { - "type": "object", + "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Body", "description": "Body to include in the HTTP call (supports data binding).", "additionalProperties": true }, "resultProperty": { "$role": "expression", + "type": "string", "title": "Result property", "description": "Property to store the result of this action. The result includes 4 properties from the http response: statusCode, reasonPhrase, content and headers. If the content is json it will be a deserialized object.", "examples": [ "dialog.contosodata" - ], - "type": "string" + ] }, "headers": { "type": "object", "title": "Headers", "description": "One or more headers to include in the request (supports data binding).", - "additionalProperties": true + "additionalProperties": { + "$role": "expression", + "type": "string", + "description": "String must contain an expression." + } }, "responseType": { + "$role": "expression", "type": "string", "title": "Response type", "description": "Defines the type of HTTP response. Automatically calls the 'Send a response' action if set to 'Activity' or 'Activities'.", @@ -4556,21 +4805,27 @@ }, "condition": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Condition", "description": "Expression to evaluate.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "actions": { "type": "array", @@ -4651,23 +4906,27 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property (named location to store information).", "examples": [ "user.age" - ], - "type": "string" + ] }, "type": { + "$role": "expression", "type": "string", "title": "Type", "description": "Type of value.", @@ -4840,25 +5099,34 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "text": { + "$role": "expression", "type": "string", "title": "Text", "description": "Information to log." }, "label": { + "$role": "expression", "type": "string", "title": "Label", "description": "Label for the trace activity (used to identify it in a list of trace activities.)" }, "traceActivity": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Send Trace Activity", "description": "If true, automatically sends a TraceActivity (view in Bot Framework Emulator).", "default": false @@ -5270,12 +5538,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "prompt": { "$kind": "Microsoft.IActivityTemplate", @@ -5314,7 +5585,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -5338,6 +5613,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -5345,30 +5621,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -5378,24 +5671,28 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the number output.", "examples": [ - "int(this.value)" - ], - "type": "string" + "@{int(this.value)}" + ] }, "defaultLocale": { + "$role": "expression", "type": "string", "title": "Default locale", "description": "Default locale.", @@ -5506,6 +5803,7 @@ "description": "Extra information for the Bot Framework Designer." }, "connectionName": { + "$role": "expression", "type": "string", "title": "Connection name", "description": "The connection name configured in Azure Web App Bot OAuth settings.", @@ -5515,14 +5813,18 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "text": { + "$role": "expression", "type": "string", "title": "Text", "description": "Text shown in the OAuth signin card.", @@ -5531,6 +5833,7 @@ ] }, "title": { + "$role": "expression", "type": "string", "title": "Title", "description": "Title shown in the OAuth signin card.", @@ -5539,19 +5842,23 @@ ] }, "timeout": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Timeout", "description": "Time out setting for the OAuth signin card.", "default": "900000" }, "property": { "$role": "expression", + "type": "string", "title": "Token property", "description": "Property to store the OAuth token result.", "examples": [ "dialog.token" - ], - "type": "string" + ] }, "invalidPrompt": { "$kind": "Microsoft.IActivityTemplate", @@ -5572,7 +5879,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -5582,22 +5893,32 @@ }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@token" - ], - "type": "string" + ] }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -8089,27 +8410,27 @@ }, "knowledgeBaseId": { "$role": "expression", + "type": "string", "title": "KnowledgeBase Id", "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", - "default": "settings.qna.knowledgebaseid", - "type": "string" + "default": "=settings.qna.knowledgebaseid" }, "endpointKey": { "$role": "expression", + "type": "string", "title": "Endpoint Key", "description": "Endpoint key for the QnA Maker KB.", - "default": "settings.qna.endpointkey", - "type": "string" + "default": "=settings.qna.endpointkey" }, "hostname": { "$role": "expression", + "type": "string", "title": "Hostname", "description": "Hostname for your QnA Maker service.", - "default": "settings.qna.hostname", + "default": "=settings.qna.hostname", "examples": [ "https://yourserver.azurewebsites.net/qnamaker" - ], - "type": "string" + ] }, "noAnswer": { "$kind": "Microsoft.IActivityTemplate", @@ -8119,18 +8440,24 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "threshold": { - "type": "number", + "$role": "expression", + "type": [ + "number", + "string" + ], "title": "Threshold", "description": "Threshold score to filter results.", "default": 0.3 }, "activeLearningCardTitle": { + "$role": "expression", "type": "string", "title": "Active learning card title", "description": "Title for active learning suggestions card.", "default": "Did you mean:" }, "cardNoMatchText": { + "$role": "expression", "type": "string", "title": "Card no match text", "description": "Text for no match option.", @@ -8144,7 +8471,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "strictFilters": { - "type": "array", + "$role": "expression", + "type": [ + "array", + "string" + ], "title": "Strict Filters", "description": "Metadata filters to use when calling the QnA Maker KB.", "items": { @@ -8164,7 +8495,11 @@ } }, "top": { - "type": "number", + "$role": "expression", + "type": [ + "number", + "string" + ], "title": "Top", "description": "The number of answers you want to retrieve.", "default": 3 @@ -8179,6 +8514,11 @@ "type": "string", "title": "RankerType", "description": "Type of Ranker.", + "enum": [ + "Default", + "QuestionOnly", + "AutoSuggestQuestion" + ], "default": "Default" } }, @@ -8689,15 +9029,22 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "options": { - "type": "object", + "$role": "expression", + "type": [ + "string", + "object" + ], "title": "Options", "description": "One or more options that are passed to the dialog that is called.", "additionalProperties": { @@ -8706,7 +9053,11 @@ } }, "activityProcessed": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Activity Processed", "description": "When set to false, the dialog that is called can process the current activity.", "default": true @@ -8770,15 +9121,23 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "dialog": { "$kind": "Microsoft.IDialog", + "$role": "expression", + "type": [ + "string", + "object" + ], "title": "Dialog name", "description": "Name of the dialog to call.", "examples": [ @@ -8787,7 +9146,11 @@ "$ref": "#/definitions/Microsoft.IDialog" }, "options": { - "type": "object", + "$role": "expression", + "type": [ + "string", + "object" + ], "title": "Options", "description": "One or more options that are passed to the dialog that is called.", "additionalProperties": { @@ -8796,7 +9159,11 @@ } }, "activityProcessed": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Activity Processed", "description": "When set to false, the dialog that is called can process the current activity.", "default": true @@ -8860,12 +9227,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "activity": { "$kind": "Microsoft.IActivityTemplate", @@ -8932,12 +9302,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "assignments": { "type": "array", @@ -8948,23 +9321,30 @@ "properties": { "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property (named location to store information).", "examples": [ "user.age" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "New value or expression.", "examples": [ - "'milk'", - "dialog.favColor", - "dialog.favColor == 'red'" - ], - "type": "string" + "='milk'", + "=dialog.favColor", + "=dialog.favColor == 'red'" + ] } } } @@ -9029,32 +9409,42 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property (named location to store information).", "examples": [ "user.age" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "New value or expression.", "examples": [ - "'milk'", - "dialog.favColor", - "dialog.favColor == 'red'" - ], - "type": "string" + "='milk'", + "=dialog.favColor", + "=dialog.favColor == 'red'" + ] } }, "additionalProperties": false, @@ -9117,26 +9507,30 @@ }, "userId": { "$role": "expression", + "type": "string", "title": "ActivityId", "description": "expression to an activityId to get the members. If none is defined then the current activity id will be used.", "examples": [ - "$lastActivity" - ], - "type": "string" + "=$lastActivity" + ] }, "connectionName": { + "$role": "expression", "type": "string", "title": "Connection Name", "description": "Connection name that was used with OAuthInput to log a user in." }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -9255,21 +9649,24 @@ }, "condition": { "$role": "expression", + "type": "string", "title": "Condition", "description": "Property to evaluate.", "examples": [ "user.favColor" - ], - "type": "string" + ] }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "cases": { "type": "array", @@ -9284,13 +9681,18 @@ "properties": { "value": { "$role": "expression", + "type": [ + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Value.", "examples": [ "'red'", "dialog.colors.red" - ], - "type": "string" + ] }, "actions": { "type": "array", @@ -9803,6 +10205,12 @@ "$ref": "#/definitions/Microsoft.Test.ITestAction" } }, + "locale": { + "type": "string", + "title": "Locale", + "description": "Set the locale for the user utterances in the script.", + "default": "en-us" + }, "enableTrace": { "type": "boolean", "title": "Enable Trace Activity", @@ -10178,12 +10586,15 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "prompt": { "$kind": "Microsoft.IActivityTemplate", @@ -10222,7 +10633,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -10246,6 +10661,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -10253,30 +10669,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -10286,22 +10719,25 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the output.", "examples": [ - "toUpper(this.value)" - ], - "type": "string" + "@{toUpper(this.value)}" + ] } }, "additionalProperties": false, @@ -10420,33 +10856,46 @@ }, "disabled": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Disabled", "description": "Optional condition which if true will disable this action.", "examples": [ "user.age > 3" - ], - "type": "string" + ] }, "name": { + "$role": "expression", "type": "string", "title": "Name", "description": "Name of the trace activity" }, "label": { + "$role": "expression", "type": "string", "title": "Label", "description": "Label for the trace activity (used to identify it in a list of trace activities.)" }, "valueType": { + "$role": "expression", "type": "string", "title": "Value type", "description": "Type of value" }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", - "description": "Property that holds the value to send as trace activity.", - "type": "string" + "description": "Property that holds the value to send as trace activity." } }, "additionalProperties": false, @@ -10557,6 +11006,28 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, + "activityId": { + "$role": "expression", + "type": "string", + "title": "Activity Id", + "dDescription": "An string expression with the activity id to update.", + "examples": [ + "=dialog.lastActivityId" + ], + "description": "String must contain an expression." + }, "activity": { "$kind": "Microsoft.IActivityTemplate", "title": "Activity", diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs index 3325fd7263..e1c14d1320 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerRecognizerTests.cs @@ -126,7 +126,7 @@ private TestFlow CreateFlow(Dialog rootDialog) .UseState(userState, conversationState) .UseLanguageGeneration() .UseAdaptiveDialogs() - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); DialogManager dm = new DialogManager(rootDialog); @@ -140,9 +140,9 @@ private AdaptiveDialog CreateQnAMakerActionDialog(MockHttpMessageHandler mockHtt { var client = new HttpClient(mockHttp); - var host = "'https://dummy-hostname.azurewebsites.net/qnamaker'"; - var knowlegeBaseId = "'dummy-id'"; - var endpointKey = "'dummy-key'"; + var host = "https://dummy-hostname.azurewebsites.net/qnamaker"; + var knowlegeBaseId = "dummy-id"; + var endpointKey = "dummy-key"; var rootDialog = new AdaptiveDialog("outer") { diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs index 5b96e9f204..c704d322e3 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/QnAMakerTests.cs @@ -1586,7 +1586,7 @@ private TestFlow CreateFlow(Dialog rootDialog) adapter .UseStorage(storage) .UseState(userState, conversationState) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); DialogManager dm = new DialogManager(rootDialog); @@ -1643,9 +1643,9 @@ private AdaptiveDialog CreateQnAMakerActionDialog(MockHttpMessageHandler mockHtt 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 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") diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests/LGGeneratorTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests/LGGeneratorTests.cs index a71cc732bd..3b1f26a48b 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests/LGGeneratorTests.cs +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests/LGGeneratorTests.cs @@ -374,7 +374,7 @@ private TestFlow CreateFlow(string lgFile, BotCallbackHandler handler) .UseResourceExplorer(resourceExplorer) .UseAdaptiveDialogs() .UseLanguageGeneration(resourceExplorer, lgFile) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); return new TestFlow(adapter, handler); } @@ -392,7 +392,7 @@ private TestFlow CreateNoResourceExplorerFlow(BotCallbackHandler handler) .UseState(userState, convoState) .UseAdaptiveDialogs() .UseLanguageGeneration() - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); return new TestFlow(adapter, handler); } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/ChoiceSetTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/ChoiceSetTests.cs index 2baffeebdd..6bb8041bf3 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/ChoiceSetTests.cs +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/ChoiceSetTests.cs @@ -5,7 +5,10 @@ using System.Collections.Generic; using Microsoft.Bot.Builder.Dialogs.Adaptive; +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; +using Microsoft.Bot.Builder.Dialogs.Adaptive.Input; using Microsoft.Bot.Builder.Dialogs.Choices; +using Microsoft.Bot.Builder.Dialogs.Declarative; using Microsoft.Bot.Builder.Dialogs.Declarative.Converters; using Microsoft.VisualStudio.TestTools.UnitTesting; using Newtonsoft.Json; @@ -19,12 +22,21 @@ public Bar() { } - public ChoiceSet Choices { get; set; } + public ObjectExpression Choices { get; set; } } [TestClass] public class ChoiceSetTests { + private JsonSerializerSettings settings = new JsonSerializerSettings() + { + Converters = new List() + { + new ChoiceSetConverter(), + new ObjectExpressionConverter() + } + }; + public TestContext TestContext { get; set; } [TestMethod] @@ -40,8 +52,8 @@ public void TestExpressionAccess() } }; - var ep = new Adaptive.ChoiceSet("choices"); - var result = ep.GetValue(state); + var ep = new ObjectExpression("choices"); + var (result, error) = ep.TryGetValue(state); Assert.AreEqual("test1", result[0].Value); Assert.AreEqual("test2", result[1].Value); Assert.AreEqual("test3", result[2].Value); @@ -51,13 +63,13 @@ public void TestExpressionAccess() public void TestValueAccess() { var state = new object(); - var ep = new Adaptive.ChoiceSet(new List() + var ep = new ObjectExpression(new ChoiceSet() { new Choice() { Value = "test1" }, new Choice() { Value = "test2" }, new Choice() { Value = "test3" } }); - var result = ep.GetValue(state); + var (result, error) = ep.TryGetValue(state); Assert.AreEqual("test1", result[0].Value); Assert.AreEqual("test2", result[1].Value); Assert.AreEqual("test3", result[2].Value); @@ -73,8 +85,8 @@ public void TestJObjectAccess() new Choice() { Value = "test3" } }; - var ep = new Adaptive.ChoiceSet(JArray.FromObject(foo)); - var result = ep.GetValue(new object()); + var ep = new ObjectExpression(new ChoiceSet(JArray.FromObject(foo))); + var (result, error) = ep.TryGetValue(new object()); Assert.AreEqual("test1", result[0].Value); Assert.AreEqual("test2", result[1].Value); Assert.AreEqual("test3", result[2].Value); @@ -84,8 +96,8 @@ public void TestJObjectAccess() public void TestStringArrayAccess() { var foo = new List() { "test1", "test2", "test3" }; - var ep = new Adaptive.ChoiceSet(JArray.FromObject(foo)); - var result = ep.GetValue(new object()); + var ep = new ObjectExpression(new ChoiceSet(JArray.FromObject(foo))); + var (result, error) = ep.TryGetValue(new object()); Assert.AreEqual("test1", result[0].Value); Assert.AreEqual("test2", result[1].Value); Assert.AreEqual("test3", result[2].Value); @@ -104,19 +116,16 @@ public void TestConverterExpressionAccess() } }; - var json = JsonConvert.SerializeObject(new + var sample = new { Choices = "test" - }); - var settings = new JsonSerializerSettings() - { - Converters = new List() { new ExpressionPropertyConverter() } }; + var json = JsonConvert.SerializeObject(sample, settings); var bar = JsonConvert.DeserializeObject(json, settings); Assert.AreEqual(typeof(Bar), bar.GetType()); - Assert.AreEqual(typeof(ChoiceSet), bar.Choices.GetType()); - var result = bar.Choices.GetValue(state); + Assert.AreEqual(typeof(ObjectExpression), bar.Choices.GetType()); + var (result, error) = bar.Choices.TryGetValue(state); Assert.AreEqual("test1", result[0].Value); Assert.AreEqual("test2", result[1].Value); Assert.AreEqual("test3", result[2].Value); @@ -129,7 +138,7 @@ public void TestConverterObjectAccess() { }; - var json = JsonConvert.SerializeObject(new + var sample = new { Choices = new List() { @@ -137,16 +146,13 @@ public void TestConverterObjectAccess() new Choice() { Value = "test2" }, new Choice() { Value = "test3" } } - }); - var settings = new JsonSerializerSettings() - { - Converters = new List() { new ExpressionPropertyConverter() } }; + var json = JsonConvert.SerializeObject(sample, settings); var bar = JsonConvert.DeserializeObject(json, settings); Assert.AreEqual(typeof(Bar), bar.GetType()); - Assert.AreEqual(typeof(ChoiceSet), bar.Choices.GetType()); - var result = bar.Choices.GetValue(state); + Assert.AreEqual(typeof(ObjectExpression), bar.Choices.GetType()); + var (result, error) = bar.Choices.TryGetValue(state); Assert.AreEqual("test1", result[0].Value); Assert.AreEqual("test2", result[1].Value); Assert.AreEqual("test3", result[2].Value); @@ -159,24 +165,53 @@ public void TestConverterStringAccess() { }; - var json = JsonConvert.SerializeObject(new + var sample = new { Choices = new List() { "test1", "test2", - "test3" + "test3" } - }); - var settings = new JsonSerializerSettings() - { - Converters = new List() { new ExpressionPropertyConverter() } }; + var json = JsonConvert.SerializeObject(sample, settings); + var bar = JsonConvert.DeserializeObject(json, settings); Assert.AreEqual(typeof(Bar), bar.GetType()); - Assert.AreEqual(typeof(ChoiceSet), bar.Choices.GetType()); - var result = bar.Choices.GetValue(state); + Assert.AreEqual(typeof(ObjectExpression), bar.Choices.GetType()); + var (result, error) = bar.Choices.TryGetValue(state); + Assert.AreEqual("test1", result[0].Value); + Assert.AreEqual("test2", result[1].Value); + Assert.AreEqual("test3", result[2].Value); + } + + [TestMethod] + public void ChoiceSet_RoundTrip() + { + var foo = new ChoiceSet() + { + new Choice() { Value = "test1" }, + new Choice() { Value = "test2" }, + new Choice() { Value = "test3" } + }; + + var bar = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(foo)); + for (int i = 0; i < foo.Count; i++) + { + Assert.AreEqual(foo[i].Value, bar[i].Value); + } + } + + [TestMethod] + public void ChoiceSet_StringArray() + { + var values = new JArray(); + values.Add("test1"); + values.Add("test2"); + values.Add("test3"); + + var result = JsonConvert.DeserializeObject(values.ToString()); Assert.AreEqual("test1", result[0].Value); Assert.AreEqual("test2", result[1].Value); Assert.AreEqual("test3", result[2].Value); diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/ExpressionPropertyTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/ExpressionPropertyTests.cs new file mode 100644 index 0000000000..97b3b954d3 --- /dev/null +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/ExpressionPropertyTests.cs @@ -0,0 +1,702 @@ +// Licensed under the MIT License. +// Copyright (c) Microsoft Corporation. All rights reserved. +#pragma warning disable SA1402 // File may only contain a single type +#pragma warning disable SA1649 // File name should match first type name +#pragma warning disable SA1202 // Elements should be ordered by access +#pragma warning disable SA1602 // Enumeration items should be documented +#pragma warning disable SA1201 // Elements should appear in the correct order + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Drawing; +using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters; +using Microsoft.Bot.Builder.Dialogs.Adaptive.Input; +using Microsoft.Bot.Builder.Dialogs.Choices; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using static Microsoft.Bot.Builder.Dialogs.Adaptive.Actions.EditArray; + +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests +{ + [TestClass] + public class ExpressionPropertyTests + { + public TestContext TestContext { get; set; } + + private object data = new + { + test = "hello", + T = true, + testEnum = TestEnum.Three, + F = false, + ByteNum = 1, + ShortNum = 2, + UShortNum = 3, + IntNum = 4, + UIntNum = 5, + LongNum = 6, + ULongNum = 7, + FloatNum = 3.1F, + DoubleNum = 3.1D, + StrArr = new List() { "a", "b", "c" }, + Obj = new { x = "yo", y = 42 } + }; + + [TestMethod] + public void ExpressionPropertyTests_ValueTests() + { + TestExpressionPropertyWithValue("1", 1); + TestExpressionPropertyWithValue("2", 2); + TestExpressionPropertyWithValue("3", 3); + TestExpressionPropertyWithValue("5", 5); + TestExpressionPropertyWithValue("6", 6); + TestExpressionPropertyWithValue("7", 7); + TestExpressionPropertyWithValue("3.1", 3.1D); + } + + [TestMethod] + public void ExpressionPropertyTests_BindingTests() + { + TestWithData(data); + } + + [TestMethod] + public void ExpressionPropertyTests_JObjectBindingTests() + { + TestWithData(JObject.FromObject(data)); + } + + public void TestWithData(object data) + { + TestExpressionPropertyWithValue("ByteNum", 1, data); + TestExpressionPropertyWithValue("=ByteNum", 1, data); + + TestExpressionPropertyWithValue("ShortNum", 2, data); + TestExpressionPropertyWithValue("=ShortNum", 2, data); + + TestExpressionPropertyWithValue("UShortNum", 3, data); + TestExpressionPropertyWithValue("=UShortNum", 3, data); + + TestExpressionPropertyWithValue("UIntNum", 5, data); + TestExpressionPropertyWithValue("=UIntNum", 5, data); + + TestExpressionPropertyWithValue("ULongNum", 7, data); + TestExpressionPropertyWithValue("=ULongNum", 7, data); + + TestExpressionPropertyWithValue("DoubleNum", 3.1D, data); + TestExpressionPropertyWithValue("=DoubleNum", 3.1D, data); + + var list = new List() { "a", "b", "c" }; + TestExpressionPropertyWithValue>("StrArr", list, data); + TestExpressionPropertyWithValue>("=StrArr", list, data); + + TestExpressionPropertyWithValue>("createArray('a','b','c')", list, data); + TestExpressionPropertyWithValue>("=createArray('a','b','c')", list, data); + } + + public void TestExpressionPropertyWithValue(string value, T expected, object memory = null) + { + var ep = new ExpressionProperty(value); + var (result, error) = ep.TryGetValue(memory ?? new object()); + if (result is ICollection) + { + CollectionAssert.AreEqual((ICollection)expected, (ICollection)result); + } + else + { + Assert.AreEqual(expected, result); + } + + Assert.IsNull(error); + } + + public void TestErrorExpression(string value, object memory = null) + { + var ep = new ExpressionProperty(value); + var (result, error) = ep.TryGetValue(memory ?? new object()); + Assert.IsNotNull(error); + } + + [TestMethod] + public void TestExpressionAccess() + { + var state = new + { + test = new Foo() + { + Name = "Test", + Age = 22 + } + }; + + var ep = new ExpressionProperty("test"); + var (result, error) = ep.TryGetValue(state); + Assert.AreEqual("Test", result.Name); + Assert.AreEqual(22, result.Age); + } + + [TestMethod] + public void TestValueAccess() + { + var foo = new Foo() + { + Name = "Test", + Age = 22 + }; + + var ep = new ExpressionProperty(foo); + var (result, error) = ep.TryGetValue(new object()); + Assert.AreEqual("Test", result.Name); + Assert.AreEqual(22, result.Age); + } + + [TestMethod] + public void TestJObjectAccess() + { + var foo = new Foo() + { + Name = "Test", + Age = 22 + }; + + var ep = new ExpressionProperty(JObject.FromObject(foo)); + var (result, error) = ep.TryGetValue(new object()); + Assert.AreEqual("Test", result.Name); + Assert.AreEqual(22, result.Age); + } + + [TestMethod] + public void TestConverterExpressionAccess() + { + var state = new + { + test = new Foo() + { + Name = "Test", + Age = 22 + } + }; + + var json = JsonConvert.SerializeObject(new + { + Foo = "test" + }); + var settings = new JsonSerializerSettings() + { + Converters = new List() { new ExpressionPropertyConverter() } + }; + + var bar = JsonConvert.DeserializeObject(json, settings); + Assert.AreEqual(typeof(Blat), bar.GetType()); + Assert.AreEqual(typeof(ExpressionProperty), bar.Foo.GetType()); + var (foo, error) = bar.Foo.TryGetValue(state); + Assert.AreEqual("Test", foo.Name); + Assert.AreEqual(22, foo.Age); + } + + [TestMethod] + public void TestConverterObjectAccess() + { + var state = new + { + }; + + var json = JsonConvert.SerializeObject(new + { + Foo = new + { + Name = "Test", + Age = 22 + } + }); + var settings = new JsonSerializerSettings() + { + Converters = new List() { new ExpressionPropertyConverter() } + }; + + var bar = JsonConvert.DeserializeObject(json, settings); + Assert.AreEqual(typeof(Blat), bar.GetType()); + Assert.AreEqual(typeof(ExpressionProperty), bar.Foo.GetType()); + var (foo, error) = bar.Foo.TryGetValue(state); + Assert.AreEqual("Test", foo.Name); + Assert.AreEqual(22, foo.Age); + } + + [TestMethod] + public void ExpressionPropertyTests_TestImplicitCasts() + { + var data = new object(); + var test = new ImplicitCastTest() + { + Str = "test", + Int = "13", + Number = "3.14", + Enm = "two", + Bool = "true" + }; + + Assert.AreEqual("test", test.Str.TryGetValue(data).Value); + Assert.AreEqual(13, test.Int.TryGetValue(data).Value); + Assert.AreEqual(3.14F, test.Number.TryGetValue(data).Value); + Assert.AreEqual(TestEnum.Two, test.Enm.TryGetValue(data).Value); + Assert.AreEqual(true, test.Bool.TryGetValue(data).Value); + + test.Str = "='test2'"; + test.Int = "=113"; + test.Number = "=13.14"; + test.Enm = "=three"; + test.Bool = "=true"; + + Assert.AreEqual("test2", test.Str.TryGetValue(data).Value); + Assert.AreEqual(113, test.Int.TryGetValue(data).Value); + Assert.AreEqual(13.14F, test.Number.TryGetValue(data).Value); + Assert.AreEqual(TestEnum.Three, test.Enm.TryGetValue(data).Value); + Assert.AreEqual(true, test.Bool.TryGetValue(data).Value); + + var json = JsonConvert.SerializeObject(test, settings: settings); + var test2 = JsonConvert.DeserializeObject(json, settings: settings); + Assert.AreEqual("test2", test2.Str.TryGetValue(data).Value); + Assert.AreEqual(113, test2.Int.TryGetValue(data).Value); + Assert.AreEqual(13.14F, test2.Number.TryGetValue(data).Value); + Assert.AreEqual(TestEnum.Three, test2.Enm.TryGetValue(data).Value); + Assert.AreEqual(true, test2.Bool.TryGetValue(data).Value); + } + + [TestMethod] + public void ExpressionPropertyTests_StringExpression() + { + var data = new + { + test = "joe" + }; + var str = new StringExpression("test"); + Assert.IsNull(str.Expression); + Assert.IsNotNull(str.Value); + Assert.AreEqual(str.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(str, settings: settings), settings: settings).ToString()); + var (result, error) = str.TryGetValue(data); + Assert.AreEqual("test", result); + Assert.IsNull(error); + + str = new StringExpression("=test"); + Assert.IsNotNull(str.Expression); + Assert.IsNull(str.Value); + Assert.AreEqual(str.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(str, settings: settings), settings: settings).ToString()); + (result, error) = str.TryGetValue(data); + Assert.AreEqual("joe", result); + Assert.IsNull(error); + + str = new StringExpression("Hello @{test}"); + Assert.IsNull(str.Expression); + Assert.IsNotNull(str.Value); + Assert.AreEqual(str.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(str, settings: settings), settings: settings).ToString()); + (result, error) = str.TryGetValue(data); + Assert.AreEqual("Hello joe", result); + Assert.IsNull(error); + } + + [TestMethod] + public void ExpressionPropertyTests_ValueExpression() + { + var data = new + { + test = new { x = 13 } + }; + + var val = new ValueExpression("test"); + Assert.IsNull(val.Expression); + Assert.IsNotNull(val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + var (result, error) = val.TryGetValue(data); + Assert.AreEqual("test", result); + Assert.IsNull(error); + + val = new ValueExpression("=test"); + Assert.IsNotNull(val.Expression); + Assert.IsNull(val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(JsonConvert.SerializeObject(data.test), JsonConvert.SerializeObject(result)); + Assert.IsNull(error); + + val = new ValueExpression(data.test); + Assert.IsNull(val.Expression); + Assert.IsNotNull(val.Value); + Assert.AreEqual(JsonConvert.SerializeObject(data.test, settings), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(JsonConvert.SerializeObject(data.test), JsonConvert.SerializeObject(result)); + Assert.IsNull(error); + + val = new ValueExpression("Hello @{test.x}"); + Assert.IsNull(val.Expression); + Assert.IsNotNull(val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual("Hello 13", result); + Assert.IsNull(error); + } + + [TestMethod] + public void ExpressionPropertyTests_BoolExpression() + { + var data = new + { + test = true + }; + + var val = new BoolExpression("true"); + Assert.IsNotNull(val.Expression); + Assert.AreEqual(default(bool), val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + var (result, error) = val.TryGetValue(data); + Assert.IsTrue(result); + Assert.IsNull(error); + + val = new BoolExpression("=true"); + Assert.IsNotNull(val.Expression); + Assert.AreEqual(default(bool), val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.IsTrue(result); + Assert.IsNull(error); + + val = new BoolExpression(true); + Assert.IsNull(val.Expression); + Assert.IsTrue(val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.IsTrue(result); + Assert.IsNull(error); + + val = new BoolExpression("=test"); + Assert.IsNotNull(val.Expression); + Assert.AreEqual(default(bool), val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.IsTrue(result); + Assert.IsNull(error); + } + + [TestMethod] + public void ExpressionPropertyTests_EnumExpression() + { + var data = new + { + test = TestEnum.Two + }; + + var val = new EnumExpression("three"); + Assert.IsNull(val.Expression); + Assert.AreEqual(TestEnum.Three, val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + var (result, error) = val.TryGetValue(data); + Assert.AreEqual(TestEnum.Three, result); + Assert.IsNull(error); + + val = new EnumExpression("=three"); + Assert.IsNull(val.Expression); + Assert.AreEqual(TestEnum.Three, val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(TestEnum.Three, result); + Assert.IsNull(error); + + val = new EnumExpression("=test"); + Assert.IsNotNull(val.Expression); + Assert.AreEqual(default(TestEnum), val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(TestEnum.Two, result); + Assert.IsNull(error); + + val = new EnumExpression(TestEnum.Three); + Assert.IsNull(val.Expression); + Assert.AreEqual(TestEnum.Three, val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(TestEnum.Three, result); + Assert.IsNull(error); + + val = new EnumExpression("garbage"); + Assert.IsNotNull(val.Expression); + Assert.AreEqual(default(TestEnum), val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(default(TestEnum), result); + Assert.IsNull(error); + + val = new EnumExpression("=sum(garbage)"); + Assert.IsNotNull(val.Expression); + Assert.AreEqual(default(TestEnum), val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(default(TestEnum), result); + Assert.IsNotNull(error); + } + + [TestMethod] + public void ExpressionPropertyTests_IntExpression() + { + TestNumberExpression(new IntExpression(), 13); + } + + [TestMethod] + public void ExpressionPropertyTests_FloatExpression() + { + TestNumberExpression(new NumberExpression(), 3.14F); + } + + private void TestNumberExpression(TExpression val, TValue expected) + where TExpression : ExpressionProperty, new() + { + var data = new + { + test = expected + }; + + val.SetValue("test"); + Assert.IsNotNull(val.Expression); + Assert.AreEqual(default(TValue), val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + var (result, error) = val.TryGetValue(data); + Assert.AreEqual(expected, result); + Assert.IsNull(error); + + val.SetValue("=test"); + Assert.IsNotNull(val.Expression); + Assert.AreEqual(default(TValue), val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(expected, result); + Assert.IsNull(error); + + val.SetValue($"{expected}"); + Assert.IsNotNull(val.Expression); + Assert.AreEqual(default(TValue), val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(expected, result); + Assert.IsNull(error); + + val.SetValue($"={expected}"); + Assert.IsNotNull(val.Expression); + Assert.AreEqual(default(TValue), val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(expected, result); + Assert.IsNull(error); + + val.SetValue(expected); + Assert.IsNull(val.Expression); + Assert.AreEqual(expected, val.Value); + Assert.AreEqual(val.ToString(), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(val, settings: settings), settings: settings).ToString()); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(expected, result); + Assert.IsNull(error); + } + + [TestMethod] + public void ExpressionPropertyTests_ObjectExpression() + { + var data = new + { + test = new Foo() + { + Age = 13, + Name = "joe" + } + }; + + var val = new ObjectExpression("test"); + Assert.IsNotNull(val.Expression); + Assert.IsNull(val.Value); + var (result, error) = val.TryGetValue(data); + Assert.AreEqual(13, result.Age); + Assert.AreEqual("joe", result.Name); + Assert.IsNull(error); + + val = new ObjectExpression("=test"); + Assert.IsNotNull(val.Expression); + Assert.IsNull(val.Value); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(13, result.Age); + Assert.AreEqual("joe", result.Name); + Assert.IsNull(error); + + val = new ObjectExpression(data.test); + Assert.IsNull(val.Expression); + Assert.IsNotNull(val.Value); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(13, result.Age); + Assert.AreEqual("joe", result.Name); + Assert.IsNull(error); + + val = new ObjectExpression(JObject.FromObject(data.test)); + Assert.IsNull(val.Expression); + Assert.IsNotNull(val.Value); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(13, result.Age); + Assert.AreEqual("joe", result.Name); + Assert.IsNull(error); + } + + [TestMethod] + public void ExpressionPropertyTests_ArrayExpressionString() + { + var data = new + { + test = new ArrFoo() + { + Strings = new List() + { + "a", "b", "c" + } + } + }; + + var val = new ArrayExpression("test.Strings"); + Assert.IsNotNull(val.Expression); + Assert.IsNull(val.Value); + var (result, error) = val.TryGetValue(data); + Assert.AreEqual(JsonConvert.SerializeObject(data.test.Strings, settings), JsonConvert.SerializeObject(result, settings: settings)); + CollectionAssert.AreEqual(data.test.Strings, result); + + val = new ArrayExpression("=test.Strings"); + Assert.IsNotNull(val.Expression); + Assert.IsNull(val.Value); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(JsonConvert.SerializeObject(data.test.Strings, settings), JsonConvert.SerializeObject(result, settings: settings)); + CollectionAssert.AreEqual(data.test.Strings, result); + + val = new ArrayExpression(data.test.Strings); + Assert.IsNull(val.Expression); + Assert.IsNotNull(val.Value); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(JsonConvert.SerializeObject(data.test.Strings, settings), JsonConvert.SerializeObject(result, settings: settings)); + CollectionAssert.AreEqual(data.test.Strings, result); + + val = new ArrayExpression(data.test.Strings); + Assert.IsNull(val.Expression); + Assert.IsNotNull(val.Value); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(JsonConvert.SerializeObject(data.test.Strings, settings), JsonConvert.SerializeObject(result, settings: settings)); + CollectionAssert.AreEqual(data.test.Strings, result); + } + + [TestMethod] + public void ExpressionPropertyTests_ArrayExpressionObject() + { + var data = new + { + test = new ArrFoo() + { + Objects = new List() + { + new Foo() + { + Age = 13, + Name = "joe" + } + } + } + }; + + var val = new ArrayExpression("test.Objects"); + Assert.IsNotNull(val.Expression); + Assert.IsNull(val.Value); + var (result, error) = val.TryGetValue(data); + CollectionAssert.AreEqual(data.test.Objects, result); + + val = new ArrayExpression("=test.Objects"); + Assert.IsNotNull(val.Expression); + Assert.IsNull(val.Value); + (result, error) = val.TryGetValue(data); + CollectionAssert.AreEqual(data.test.Objects, result); + + val = new ArrayExpression(data.test.Objects); + Assert.IsNull(val.Expression); + Assert.IsNotNull(val.Value); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(JsonConvert.SerializeObject(data.test.Objects, settings), JsonConvert.SerializeObject(result, settings)); + + val = new ArrayExpression(JArray.FromObject(data.test.Objects)); + Assert.IsNull(val.Expression); + Assert.IsNotNull(val.Value); + (result, error) = val.TryGetValue(data); + Assert.AreEqual(JsonConvert.SerializeObject(data.test.Objects, settings), JsonConvert.SerializeObject(result, settings)); + } + + private JsonSerializerSettings settings = new JsonSerializerSettings() + { + Formatting = Formatting.Indented, + Converters = new List() + { + new StringExpressionConverter(), + new ValueExpressionConverter(), + new BoolExpressionConverter(), + new IntExpressionConverter(), + new NumberExpressionConverter(), + new ExpressionPropertyConverter(), + new ExpressionPropertyConverter(), + new ExpressionPropertyConverter(), + new ExpressionPropertyConverter(), + new ExpressionPropertyConverter(), + new ExpressionPropertyConverter(), + new ExpressionPropertyConverter(), + new EnumExpressionConverter(), + new EnumExpressionConverter(), + new EnumExpressionConverter(), + new ChoiceSetConverter() + } + }; + + private class Blat + { + public ExpressionProperty Foo { get; set; } + } + + private class Foo + { + public Foo() + { + } + + public string Name { get; set; } + + public int Age { get; set; } + } + + private class ArrFoo + { + public List Objects { get; set; } + + public List Strings { get; set; } + } + + public class ImplicitCastTest + { + public StringExpression Str { get; set; } = new StringExpression(); + + public IntExpression Int { get; set; } = new IntExpression(); + + public EnumExpression Enm { get; set; } = new EnumExpression(); + + public NumberExpression Number { get; set; } = new NumberExpression(); + + public ValueExpression Value { get; set; } = new ValueExpression(); + + public BoolExpression Bool { get; set; } = new BoolExpression(); + } + + [JsonConverter(typeof(StringEnumConverter), /*camelCase*/ true)] + public enum TestEnum + { + One, + Two, + Three + } + } +} diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Break.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Break.test.dialog index 633a5314a0..33490d1234 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Break.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Break.test.dialog @@ -17,37 +17,37 @@ "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "1" + "value": "=1" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "2" + "value": "=2" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "3" + "value": "=3" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "4" + "value": "=4" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "5" + "value": "=5" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "6" + "value": "=6" }, { "$kind": "Microsoft.Foreach", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Continue.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Continue.test.dialog index 146fe97ba5..59993adf5f 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Continue.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Continue.test.dialog @@ -17,37 +17,37 @@ "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "1" + "value": "=1" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "2" + "value": "=2" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "3" + "value": "=3" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "4" + "value": "=4" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "5" + "value": "=5" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "6" + "value": "=6" }, { "$kind": "Microsoft.Foreach", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto.test.dialog index dd924e2633..c74346021c 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto.test.dialog @@ -29,7 +29,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$counter", - "value": "$counter + 1" + "value": "=$counter + 1" }, { "$kind": "Microsoft.GotoAction", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto_Parent.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto_Parent.test.dialog index 87c0689dc6..de2036af69 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto_Parent.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto_Parent.test.dialog @@ -44,7 +44,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.counter", - "value": "user.counter + 1" + "value": "=user.counter + 1" }, { "$kind": "Microsoft.GotoAction", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto_Switch.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto_Switch.test.dialog index a350cb46af..df8e237933 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto_Switch.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionScopeTests/ActionScope_Goto_Switch.test.dialog @@ -10,7 +10,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$counter", - "value": "0" + "value": "=0" }, { "id": "loopTop", @@ -24,7 +24,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$counter", - "value": "$counter + 1" + "value": "=$counter + 1" }, { "$kind": "Microsoft.GotoAction", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceInput.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceInput.test.dialog index 9d652db229..8025856590 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceInput.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceInput.test.dialog @@ -10,19 +10,17 @@ "actions": [ { "$kind": "Microsoft.ChoiceInput", - "choices": { - "value": [ - { - "value": "red" - }, - { - "value": "green" - }, - { - "value": "blue" - } - ] - }, + "choices": [ + { + "value": "red" + }, + { + "value": "green" + }, + { + "value": "blue" + } + ], "styles": 2, "property": "user.color", "prompt": "Please select a color:", @@ -34,19 +32,17 @@ }, { "$kind": "Microsoft.ChoiceInput", - "choices": { - "value": [ - { - "value": "red" - }, - { - "value": "green" - }, - { - "value": "blue" - } - ] - }, + "choices": [ + { + "value": "red" + }, + { + "value": "green" + }, + { + "value": "blue" + } + ], "styles": 2, "alwaysPrompt": true, "property": "user.color", @@ -59,19 +55,17 @@ }, { "$kind": "Microsoft.ChoiceInput", - "choices": { - "value": [ - { - "value": "red" - }, - { - "value": "green" - }, - { - "value": "blue" - } - ] - }, + "choices": [ + { + "value": "red" + }, + { + "value": "green" + }, + { + "value": "blue" + } + ], "styles": 2, "alwaysPrompt": true, "property": "user.color", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceInput_WithLocale.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceInput_WithLocale.test.dialog index 7a70897629..d69870d26a 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceInput_WithLocale.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceInput_WithLocale.test.dialog @@ -10,19 +10,17 @@ "actions": [ { "$kind": "Microsoft.ChoiceInput", - "choices": { - "value": [ - { - "value": "red" - }, - { - "value": "green" - }, - { - "value": "blue" - } - ] - }, + "choices": [ + { + "value": "red" + }, + { + "value": "green" + }, + { + "value": "blue" + } + ], "styles": 2, "property": "user.color", "prompt": "Please select a color:", @@ -34,19 +32,17 @@ }, { "$kind": "Microsoft.ChoiceInput", - "choices": { - "value": [ - { - "value": "red" - }, - { - "value": "green" - }, - { - "value": "blue" - } - ] - }, + "choices": [ + { + "value": "red" + }, + { + "value": "green" + }, + { + "value": "blue" + } + ], "styles": 2, "alwaysPrompt": true, "property": "user.color", @@ -59,19 +55,17 @@ }, { "$kind": "Microsoft.ChoiceInput", - "choices": { - "value": [ - { - "value": "red" - }, - { - "value": "green" - }, - { - "value": "blue" - } - ] - }, + "choices": [ + { + "value": "red" + }, + { + "value": "green" + }, + { + "value": "blue" + } + ], "styles": 2, "alwaysPrompt": true, "property": "user.color", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceStringInMemory.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceStringInMemory.test.dialog index 61aab5cfc1..2845250dfc 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceStringInMemory.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoiceStringInMemory.test.dialog @@ -11,13 +11,11 @@ { "$kind": "Microsoft.SetProperty", "property": "user.choices", - "value": "json('[\"red\", \"green\", \"blue\"]')" + "value": "=json('[\"red\", \"green\", \"blue\"]')" }, { "$kind": "Microsoft.ChoiceInput", - "choices": { - "expression": "user.choices" - }, + "choices": "user.choices", "styles": 2, "property": "user.color", "prompt": "Please select a color:", @@ -29,9 +27,7 @@ }, { "$kind": "Microsoft.ChoiceInput", - "choices": { - "expression": "user.choices" - }, + "choices": "user.choices", "styles": 2, "alwaysPrompt": true, "property": "user.color", @@ -44,9 +40,7 @@ }, { "$kind": "Microsoft.ChoiceInput", - "choices": { - "expression": "user.choices" - }, + "choices": "user.choices", "styles": 2, "alwaysPrompt": true, "property": "user.color", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoicesInMemory.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoicesInMemory.test.dialog index d98296fc9a..0a22ce4caf 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoicesInMemory.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ChoicesInMemory.test.dialog @@ -11,13 +11,11 @@ { "$kind": "Microsoft.SetProperty", "property": "user.choices", - "value": "json('[{\"value\": \"red\"}, {\"value\": \"green\"}, {\"value\": \"blue\"}]')" + "value": "=json('[{\"value\": \"red\"}, {\"value\": \"green\"}, {\"value\": \"blue\"}]')" }, { "$kind": "Microsoft.ChoiceInput", - "choices": { - "expression": "user.choices" - }, + "choices": "user.choices", "styles": 2, "property": "user.color", "prompt": "Please select a color:", @@ -29,9 +27,7 @@ }, { "$kind": "Microsoft.ChoiceInput", - "choices": { - "expression": "user.choices" - }, + "choices": "user.choices", "styles": 2, "alwaysPrompt": true, "property": "user.color", @@ -44,9 +40,7 @@ }, { "$kind": "Microsoft.ChoiceInput", - "choices": { - "expression": "user.choices" - }, + "choices": "user.choices", "styles": 2, "alwaysPrompt": true, "property": "user.color", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ConfirmInput.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ConfirmInput.test.dialog index 9a245de886..10bee13d1d 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ConfirmInput.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ConfirmInput.test.dialog @@ -10,7 +10,7 @@ "actions": [ { "$kind": "Microsoft.ConfirmInput", - "style": 1, + "style": "auto", "property": "user.confirmed", "prompt": "yes or no", "unrecognizedPrompt": "I need a yes or no." @@ -21,7 +21,7 @@ }, { "$kind": "Microsoft.ConfirmInput", - "style": 1, + "style": "auto", "alwaysPrompt": true, "property": "user.confirmed", "prompt": "yes or no", @@ -33,7 +33,7 @@ }, { "$kind": "Microsoft.ConfirmInput", - "style": 1, + "style": "auto", "alwaysPrompt": true, "property": "user.confirmed", "prompt": "yes or no", @@ -45,12 +45,12 @@ }, { "$kind": "Microsoft.ConfirmInput", - "style": 1, + "style": "auto", "alwaysPrompt": true, "property": "user.confirmed", "prompt": "yes or no", "unrecognizedPrompt": "I need a yes or no.", - "outputFormat": "concat('confirmation: ', this.value)" + "outputFormat": "=concat('confirmation: ', this.value)" }, { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DatetimeInput.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DatetimeInput.test.dialog index 09f9862c23..83f4c337b7 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DatetimeInput.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DatetimeInput.test.dialog @@ -12,7 +12,7 @@ "$kind": "Microsoft.DateTimeInput", "property": "user.date", "prompt": "Please enter a date.", - "outputFormat": "this.value[0].Value" + "outputFormat": "=this.value[0].Value" }, { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteActivity.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteActivity.test.dialog index 13a710af2e..4dccdcaf3e 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteActivity.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteActivity.test.dialog @@ -14,7 +14,7 @@ }, { "$kind": "Microsoft.DeleteActivity", - "activityId": "turn.lastresult.id" + "activityId": "=turn.lastresult.id" }, { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteProperties.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteProperties.test.dialog index 18be11dddb..5c0c3e8212 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteProperties.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteProperties.test.dialog @@ -13,19 +13,19 @@ "assignments": [ { "property": "$p1", - "value": "'val1'" + "value": "='val1'" }, { "property": "$p2", - "value": "$p1" + "value": "=$p1" }, { "property": "$p3", - "value": "13" + "value": "=13" }, { "property": "$p4", - "value": "'billybob'" + "value": "='billybob'" } ] }, diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteProperty.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteProperty.test.dialog index 5b64906bf1..2985208f6e 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteProperty.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_DeleteProperty.test.dialog @@ -11,7 +11,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$p1", - "value": "'val1'" + "value": "='val1'" }, { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Foreach.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Foreach.test.dialog index baa548878f..f0ce0e1046 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Foreach.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Foreach.test.dialog @@ -16,17 +16,17 @@ { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", - "value": "1" + "value": "=1" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", - "value": "2" + "value": "=2" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", - "value": "3" + "value": "=3" }, { "$kind": "Microsoft.Foreach", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ForeachPage.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ForeachPage.test.dialog index 38cd3c8a7a..38ff07c77a 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ForeachPage.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ForeachPage.test.dialog @@ -17,37 +17,37 @@ "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "1" + "value": "=1" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "2" + "value": "=2" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "3" + "value": "=3" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "4" + "value": "=4" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "5" + "value": "=5" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "6" + "value": "=6" }, { "$kind": "Microsoft.ForeachPage", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ForeachPage_Partial.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ForeachPage_Partial.test.dialog index c08e1ba52c..c150db565d 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ForeachPage_Partial.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_ForeachPage_Partial.test.dialog @@ -17,31 +17,31 @@ "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "1" + "value": "=1" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "2" + "value": "=2" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "3" + "value": "=3" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "4" + "value": "=4" }, { "$kind": "Microsoft.EditArray", "itemsProperty": "dialog.todo", "changeType": "push", - "value": "5" + "value": "=5" }, { "$kind": "Microsoft.ForeachPage", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_NumberInput.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_NumberInput.test.dialog index a42bbdd5e9..293c865919 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_NumberInput.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_NumberInput.test.dialog @@ -10,7 +10,7 @@ "actions": [ { "$kind": "Microsoft.NumberInput", - "outputFormat": "int(this.value)", + "outputFormat": "=int(this.value)", "property": "user.userProfile.Age", "prompt": "Please enter your age.", "unrecognizedPrompt": "The value entered must be greater than 0 and less than 150.", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_NumberInputWithVAlueExpression.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_NumberInputWithVAlueExpression.test.dialog index a3cc0ad538..bef82648ce 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_NumberInputWithVAlueExpression.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_NumberInputWithVAlueExpression.test.dialog @@ -25,7 +25,7 @@ { "$kind": "Microsoft.NumberInput", "property": "turn.age", - "value": "@number", + "value": "=@number", "prompt": "What is your age?", "maxTurnCount": 1 }, diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SendActivity.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SendActivity.test.dialog index 772389349a..4e847ed0c9 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SendActivity.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SendActivity.test.dialog @@ -16,7 +16,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$disabled", - "value": "true" + "value": "=true" }, { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SetProperties.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SetProperties.test.dialog index e616d58e01..56f4f58c52 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SetProperties.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SetProperties.test.dialog @@ -13,19 +13,19 @@ "assignments": [ { "property": "$p1", - "value": "'val1'" + "value": "='val1'" }, { "property": "$p2", - "value": "$p1" + "value": "=$p1" }, { "property": "$p3", - "value": "13" + "value": "=13" }, { "property": "$p4", - "value": "'billybob'" + "value": "='billybob'" } ] }, diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SetProperty.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SetProperty.test.dialog index 6fdcb5de32..fbab0d609b 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SetProperty.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_SetProperty.test.dialog @@ -11,7 +11,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$p1", - "value": "'val1'" + "value": "='val1'" }, { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch.test.dialog index efcad0f48b..cf1bcb576e 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch.test.dialog @@ -11,7 +11,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.name", - "value": "'frank'" + "value": "='frank'" }, { "$kind": "Microsoft.SwitchCondition", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Bool.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Bool.test.dialog index fe7f68805b..a9212e224b 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Bool.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Bool.test.dialog @@ -11,7 +11,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.isVip", - "value": "True" + "value": "=true" }, { "$kind": "Microsoft.SwitchCondition", @@ -24,7 +24,7 @@ ], "cases": [ { - "value": "True", + "value": "true", "actions": [ { "$kind": "Microsoft.SendActivity", @@ -33,7 +33,7 @@ ] }, { - "value": "False", + "value": "false", "actions": [ { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Default.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Default.test.dialog index 6f2ee1081f..8b71820881 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Default.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Default.test.dialog @@ -11,7 +11,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.name", - "value": "'Zoidberg'" + "value": "='Zoidberg'" }, { "$kind": "Microsoft.SwitchCondition", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Number.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Number.test.dialog index 75cea3e7b8..32beb90a1b 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Number.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_Switch_Number.test.dialog @@ -11,7 +11,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.age", - "value": "22" + "value": "=22" }, { "$kind": "Microsoft.SwitchCondition", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TextInput.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TextInput.test.dialog index 6282ed192f..08f0d56172 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TextInput.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TextInput.test.dialog @@ -16,7 +16,7 @@ "validations": [ "this.value.Length > 3" ], - "outputFormat": "toUpper(this.value)" + "outputFormat": "@{toUpper(this.value)}" }, { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TextInputWithValueExpression.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TextInputWithValueExpression.test.dialog index 3f023fbf4a..3831e07478 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TextInputWithValueExpression.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TextInputWithValueExpression.test.dialog @@ -11,12 +11,12 @@ { "$kind": "Microsoft.SetProperty", "property": "dialog.firstName", - "value": "'lu'" + "value": "lu" }, { "$kind": "Microsoft.SetProperty", "property": "dialog.lastName", - "value": "'han'" + "value": "han" }, { "$kind": "Microsoft.IfCondition", @@ -31,7 +31,7 @@ "validations": [ "this.value.Length > 3" ], - "value": "concat(toUpper($firstName),toUpper($lastName))" + "value": "=concat(toUpper($firstName),toUpper($lastName))" } ] }, diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TraceActivity.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TraceActivity.test.dialog index 7844a019fb..fe3915b04f 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TraceActivity.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_TraceActivity.test.dialog @@ -12,13 +12,13 @@ { "$kind": "Microsoft.SetProperty", "property": "user.name", - "value": "'frank'" + "value": "='frank'" }, { "$kind": "Microsoft.TraceActivity", "name": "test", "valueType": "user", - "value": "user" + "value": "=user" }, { "$kind": "Microsoft.TraceActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_UpdateActivity.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_UpdateActivity.test.dialog index 2711b4a13f..623cb04a42 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_UpdateActivity.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/ActionTests/Action_UpdateActivity.test.dialog @@ -14,7 +14,7 @@ }, { "$kind": "Microsoft.UpdateActivity", - "activityId": "turn.lastresult.id", + "activityId": "=turn.lastresult.id", "activity": "text2" }, { diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionAlwaysWithFailedValidation.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionAlwaysWithFailedValidation.test.dialog index 3f78f8a30f..d0ffdb0bdd 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionAlwaysWithFailedValidation.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionAlwaysWithFailedValidation.test.dialog @@ -55,7 +55,7 @@ { "$kind": "Microsoft.SetProperty", "property": "turn.interrupted", - "value": "False" + "value": "=False" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNever.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNever.test.dialog index d50dac1c62..e11f37cdc4 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNever.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNever.test.dialog @@ -46,7 +46,7 @@ { "$kind": "Microsoft.SetProperty", "property": "turn.processInput", - "value": "True" + "value": "=True" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithInvalidInput.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithInvalidInput.test.dialog index 8f0b564e75..1af4800f94 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithInvalidInput.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithInvalidInput.test.dialog @@ -51,7 +51,7 @@ { "$kind": "Microsoft.SetProperty", "property": "turn.processInput", - "value": "True" + "value": "=True" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithMaxCount.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithMaxCount.test.dialog index 85aef1c9f4..7e9f08d557 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithMaxCount.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithMaxCount.test.dialog @@ -48,7 +48,7 @@ { "$kind": "Microsoft.SetProperty", "property": "turn.processInput", - "value": "True" + "value": "=True" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithUnrecognizedInput.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithUnrecognizedInput.test.dialog index d8c8ec5e67..517e5ba920 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithUnrecognizedInput.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_AllowInterruptionNeverWithUnrecognizedInput.test.dialog @@ -48,7 +48,7 @@ { "$kind": "Microsoft.SetProperty", "property": "turn.processInput", - "value": "True" + "value": "=True" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_BindingOptionsAcrossAdaptiveDialogs/AdaptiveDialog_BindingOptionsAcrossAdaptiveDialogs.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_BindingOptionsAcrossAdaptiveDialogs/AdaptiveDialog_BindingOptionsAcrossAdaptiveDialogs.test.dialog index 6a3b5ae613..3c51bea06b 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_BindingOptionsAcrossAdaptiveDialogs/AdaptiveDialog_BindingOptionsAcrossAdaptiveDialogs.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_BindingOptionsAcrossAdaptiveDialogs/AdaptiveDialog_BindingOptionsAcrossAdaptiveDialogs.test.dialog @@ -16,7 +16,7 @@ { "$kind": "Microsoft.BeginDialog", "options": { - "userAge": "$age" + "userAge": "=$age" }, "dialog": "AdaptiveDialog_BindingOptionsAcrossAdaptiveDialogs.AgeDialog" } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ConditionallyAllowInterruptions.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ConditionallyAllowInterruptions.test.dialog index b7738ad127..94cce167be 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ConditionallyAllowInterruptions.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ConditionallyAllowInterruptions.test.dialog @@ -51,7 +51,7 @@ { "$kind": "Microsoft.SetProperty", "property": "turn.interrupted", - "value": "False" + "value": "=False" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_EditArray.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_EditArray.test.dialog index 27c10d6c68..b6047baaa7 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_EditArray.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_EditArray.test.dialog @@ -22,7 +22,7 @@ { "$kind": "Microsoft.EditArray", "itemsProperty": "user.todos", - "value": "dialog.todo" + "value": "=dialog.todo" }, { "$kind": "Microsoft.SendActivity", @@ -37,7 +37,7 @@ { "$kind": "Microsoft.EditArray", "itemsProperty": "user.todos", - "value": "dialog.todo" + "value": "=dialog.todo" }, { "$kind": "Microsoft.SendActivity", @@ -53,7 +53,7 @@ "$kind": "Microsoft.EditArray", "changeType": "Remove", "itemsProperty": "user.todos", - "value": "dialog.todo" + "value": "=dialog.todo" }, { "$kind": "Microsoft.SendActivity", @@ -68,7 +68,7 @@ { "$kind": "Microsoft.EditArray", "itemsProperty": "user.todos", - "value": "dialog.todo" + "value": "=dialog.todo" }, { "$kind": "Microsoft.TextInput", @@ -79,7 +79,7 @@ { "$kind": "Microsoft.EditArray", "itemsProperty": "user.todos", - "value": "dialog.todo" + "value": "=dialog.todo" }, { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_PropertySetInInterruption.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_PropertySetInInterruption.test.dialog index 08b5a32909..0bee3022fc 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_PropertySetInInterruption.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_PropertySetInInterruption.test.dialog @@ -91,7 +91,7 @@ { "$kind": "Microsoft.SetProperty", "property": "turn.interrupted", - "value": "False" + "value": "=False" } ] }, @@ -118,7 +118,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.name", - "value": "'Human'" + "value": "Human" } ] }, diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ReProcessInputProperty.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ReProcessInputProperty.test.dialog index c05115c18a..06af65d24c 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ReProcessInputProperty.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ReProcessInputProperty.test.dialog @@ -52,7 +52,7 @@ { "$kind": "Microsoft.SetProperty", "property": "turn.interrupted", - "value": "False" + "value": "=False" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ReProcessInputPropertyValidOnlyOnce.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ReProcessInputPropertyValidOnlyOnce.test.dialog index 3317678dd1..510bb82cb0 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ReProcessInputPropertyValidOnlyOnce.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/AdaptiveDialog_ReProcessInputPropertyValidOnlyOnce.test.dialog @@ -62,7 +62,7 @@ { "$kind": "Microsoft.SetProperty", "property": "turn.interrupted", - "value": "False" + "value": "=False" } ] }, @@ -77,7 +77,7 @@ { "$kind": "Microsoft.SetProperty", "property": "turn.interrupted", - "value": "False" + "value": "=False" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestBindingTwoWayAcrossAdaptiveDialogs.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestBindingTwoWayAcrossAdaptiveDialogs.test.dialog index e83eede62c..f5b12ef818 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestBindingTwoWayAcrossAdaptiveDialogs.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestBindingTwoWayAcrossAdaptiveDialogs.test.dialog @@ -17,7 +17,7 @@ "$kind": "Microsoft.BeginDialog", "resultProperty": "$age", "options": { - "userName": "$name" + "userName": "=$name" }, "dialog": { "$kind": "Microsoft.AdaptiveDialog", @@ -32,7 +32,7 @@ }, { "$kind": "Microsoft.EndDialog", - "value": "$age" + "value": "=$age" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestBindingTwoWayAcrossAdaptiveDialogsDefaultResultProperty.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestBindingTwoWayAcrossAdaptiveDialogsDefaultResultProperty.test.dialog index 232eb532f7..1301ba1f34 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestBindingTwoWayAcrossAdaptiveDialogsDefaultResultProperty.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestBindingTwoWayAcrossAdaptiveDialogsDefaultResultProperty.test.dialog @@ -17,7 +17,7 @@ "$kind": "Microsoft.BeginDialog", "resultProperty": "$userAge", "options": { - "userName2": "$userName" + "userName2": "=$userName" }, "dialog": { "$kind": "Microsoft.AdaptiveDialog", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestForeachWithPrompt.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestForeachWithPrompt.test.dialog index e7b1a63c84..8b9c70ff72 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestForeachWithPrompt.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/AdaptiveTests/TestForeachWithPrompt.test.dialog @@ -17,7 +17,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$colorChoices", - "value": "createArray('red', 'blue', 'green')" + "value": "=createArray('red', 'blue', 'green')" }, { "$kind": "Microsoft.InitProperty", @@ -37,7 +37,7 @@ { "$kind": "Microsoft.EditArray", "itemsProperty": "$userAnswers", - "value": "$answer" + "value": "=$answer" }, { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-BreadSetBreadEntity.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-BreadSetBreadEntity.dialog index 1dcbb3cc3c..1f21481142 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-BreadSetBreadEntity.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-BreadSetBreadEntity.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Bread", - "value": "@BreadEntity" + "value": "=@BreadEntity" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CancelConfirmationSet.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CancelConfirmationSet.dialog index 438f626d96..dc7aef0705 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CancelConfirmationSet.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CancelConfirmationSet.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$CancelConfirmation", - "value": "@Confirmation" + "value": "=@Confirmation" }, { "$kind": "Microsoft.IfCondition", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-ChangePropertyConfirmationSet.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-ChangePropertyConfirmationSet.dialog index 25ba492765..d7c656766d 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-ChangePropertyConfirmationSet.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-ChangePropertyConfirmationSet.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$ChangePropertyConfirmation", - "value": "@Confirmation" + "value": "=@Confirmation" }, { "$kind": "Microsoft.IfCondition", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CheeseSetCheeseEntity.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CheeseSetCheeseEntity.dialog index 06be0d2356..8534be2036 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CheeseSetCheeseEntity.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CheeseSetCheeseEntity.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Cheese", - "value": "@CheeseEntity" + "value": "=@CheeseEntity" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CompleteSetConfirmation.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CompleteSetConfirmation.dialog index 151eb7dd6d..f5f05690c9 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CompleteSetConfirmation.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-CompleteSetConfirmation.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$CompleteConfirmation", - "value": "@Confirmation" + "value": "=@Confirmation" }, { "$kind": "Microsoft.IfCondition", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-LengthSetdimension.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-LengthSetdimension.dialog index 0f9a187eda..3817d51617 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-LengthSetdimension.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-LengthSetdimension.dialog @@ -12,12 +12,12 @@ { "$kind": "Microsoft.SetProperty", "property": "$Length.number", - "value": "@dimension.number" + "value": "=@dimension.number" }, { "$kind": "Microsoft.SetProperty", "property": "$Length.units", - "value": "@dimension.units" + "value": "=@dimension.units" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-MeatSetMeatEntity.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-MeatSetMeatEntity.dialog index d703491117..8ad2ba8ce2 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-MeatSetMeatEntity.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-MeatSetMeatEntity.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Meat", - "value": "@MeatEntity" + "value": "=@MeatEntity" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-NameSetpersonName.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-NameSetpersonName.dialog index c057782bac..f90bd964f2 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-NameSetpersonName.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-NameSetpersonName.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Name", - "value": "@personName" + "value": "=@personName" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-NameSetutterance.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-NameSetutterance.dialog index 3a40e70b80..e9fd37aa72 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-NameSetutterance.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-NameSetutterance.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Name", - "value": "@utterance" + "value": "=@utterance" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-PriceSetmoney.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-PriceSetmoney.dialog index 38dbde0ea8..00c54dc83f 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-PriceSetmoney.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-PriceSetmoney.dialog @@ -12,12 +12,12 @@ { "$kind": "Microsoft.SetProperty", "property": "$Price.number", - "value": "@money.number" + "value": "=@money.number" }, { "$kind": "Microsoft.SetProperty", "property": "$Price.units", - "value": "@money.units" + "value": "=@money.units" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-PropertyToRememberSet.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-PropertyToRememberSet.dialog index 3b5da03f65..0b51a7539b 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-PropertyToRememberSet.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-PropertyToRememberSet.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$PropertyToRemember", - "value": "@PROPERTYName" + "value": "=@PROPERTYName" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-QuantitySetnumber.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-QuantitySetnumber.dialog index b4cc4d2c8c..7a8432f014 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-QuantitySetnumber.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-QuantitySetnumber.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Quantity", - "value": "@number" + "value": "=@number" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-ReadPropertyIntent.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-ReadPropertyIntent.dialog index 8aa2bd366e..387b62db81 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-ReadPropertyIntent.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/sandwich/sandwich-ReadPropertyIntent.dialog @@ -11,7 +11,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$PropertyToRemember", - "value": "@PROPERTYName" + "value": "=@PROPERTYName" }, { "$kind": "Microsoft.Ask", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-AgeSetage.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-AgeSetage.dialog index 1bca029f83..32b094c4a9 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-AgeSetage.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-AgeSetage.dialog @@ -12,12 +12,12 @@ { "$kind": "Microsoft.SetProperty", "property": "$Age.number", - "value": "@age.number" + "value": "=@age.number" }, { "$kind": "Microsoft.SetProperty", "property": "$Age.units", - "value": "@age.units" + "value": "=@age.units" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-CancelConfirmationSet.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-CancelConfirmationSet.dialog index 438f626d96..dc7aef0705 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-CancelConfirmationSet.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-CancelConfirmationSet.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$CancelConfirmation", - "value": "@Confirmation" + "value": "=@Confirmation" }, { "$kind": "Microsoft.IfCondition", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ChangePropertyConfirmationSet.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ChangePropertyConfirmationSet.dialog index 25ba492765..d7c656766d 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ChangePropertyConfirmationSet.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ChangePropertyConfirmationSet.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$ChangePropertyConfirmation", - "value": "@Confirmation" + "value": "=@Confirmation" }, { "$kind": "Microsoft.IfCondition", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-CompleteSetConfirmation.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-CompleteSetConfirmation.dialog index 151eb7dd6d..f5f05690c9 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-CompleteSetConfirmation.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-CompleteSetConfirmation.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$CompleteConfirmation", - "value": "@Confirmation" + "value": "=@Confirmation" }, { "$kind": "Microsoft.IfCondition", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-DimensionSetdimension.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-DimensionSetdimension.dialog index 56a3175d69..0b41d368e2 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-DimensionSetdimension.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-DimensionSetdimension.dialog @@ -12,12 +12,12 @@ { "$kind": "Microsoft.SetProperty", "property": "$Dimension.number", - "value": "@dimension.number" + "value": "=@dimension.number" }, { "$kind": "Microsoft.SetProperty", "property": "$Dimension.units", - "value": "@dimension.units" + "value": "=@dimension.units" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-EmailSetemail.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-EmailSetemail.dialog index eefb15df03..27981eae2d 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-EmailSetemail.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-EmailSetemail.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Email", - "value": "@email" + "value": "=@email" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Enum1SetEnum1Entity.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Enum1SetEnum1Entity.dialog index 074fa26f50..f7f5421d3f 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Enum1SetEnum1Entity.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Enum1SetEnum1Entity.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Enum1", - "value": "@Enum1Entity" + "value": "=@Enum1Entity" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Enum2SetEnum2Entity.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Enum2SetEnum2Entity.dialog index ba872daffb..658fe8827d 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Enum2SetEnum2Entity.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Enum2SetEnum2Entity.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Enum2", - "value": "@Enum2Entity" + "value": "=@Enum2Entity" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Geographyv2SetgeographyV2.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Geographyv2SetgeographyV2.dialog index 038995fb95..defd396095 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Geographyv2SetgeographyV2.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-Geographyv2SetgeographyV2.dialog @@ -12,12 +12,12 @@ { "$kind": "Microsoft.SetProperty", "property": "$Geographyv2.type", - "value": "@geographyV2.type" + "value": "=@geographyV2.type" }, { "$kind": "Microsoft.SetProperty", "property": "$Geographyv2.location", - "value": "@geographyV2.location" + "value": "=@geographyV2.location" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-KeyphrasepropertySetkeyPhrase.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-KeyphrasepropertySetkeyPhrase.dialog index 3428faa0e3..37c72b9b52 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-KeyphrasepropertySetkeyPhrase.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-KeyphrasepropertySetkeyPhrase.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Keyphraseproperty", - "value": "@keyPhrase" + "value": "=@keyPhrase" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-MoneySetmoney.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-MoneySetmoney.dialog index f5726bf3fe..2125c39bfc 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-MoneySetmoney.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-MoneySetmoney.dialog @@ -12,12 +12,12 @@ { "$kind": "Microsoft.SetProperty", "property": "$Money.number", - "value": "@money.number" + "value": "=@money.number" }, { "$kind": "Microsoft.SetProperty", "property": "$Money.units", - "value": "@money.units" + "value": "=@money.units" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-OrdinalSetordinal.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-OrdinalSetordinal.dialog index 8ca636bcdc..84e1ba66cf 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-OrdinalSetordinal.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-OrdinalSetordinal.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Ordinal", - "value": "@ordinal" + "value": "=@ordinal" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PercentageSetpercentage.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PercentageSetpercentage.dialog index 0d58d08cb5..3bacd6b3f9 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PercentageSetpercentage.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PercentageSetpercentage.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Percentage", - "value": "@percentage" + "value": "=@percentage" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PersonnameSetpersonName.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PersonnameSetpersonName.dialog index c1577cb1b2..a23438ddb9 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PersonnameSetpersonName.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PersonnameSetpersonName.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Personname", - "value": "@personName" + "value": "=@personName" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PropertyToRememberSet.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PropertyToRememberSet.dialog index 3b5da03f65..0b51a7539b 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PropertyToRememberSet.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-PropertyToRememberSet.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$PropertyToRemember", - "value": "@PROPERTYName" + "value": "=@PROPERTYName" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-QuantitySetnumber.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-QuantitySetnumber.dialog index b4cc4d2c8c..7a8432f014 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-QuantitySetnumber.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-QuantitySetnumber.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Quantity", - "value": "@number" + "value": "=@number" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ReadPropertyIntent.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ReadPropertyIntent.dialog index 8aa2bd366e..387b62db81 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ReadPropertyIntent.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ReadPropertyIntent.dialog @@ -11,7 +11,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$PropertyToRemember", - "value": "@PROPERTYName" + "value": "=@PROPERTYName" }, { "$kind": "Microsoft.Ask", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-TemperatureSettemperature.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-TemperatureSettemperature.dialog index 158b070e00..70675fdb53 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-TemperatureSettemperature.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-TemperatureSettemperature.dialog @@ -12,12 +12,12 @@ { "$kind": "Microsoft.SetProperty", "property": "$Temperature.number", - "value": "@temperature.number" + "value": "=@temperature.number" }, { "$kind": "Microsoft.SetProperty", "property": "$Temperature.units", - "value": "@temperature.units" + "value": "=@temperature.units" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-UrlSeturl.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-UrlSeturl.dialog index 24e956e670..189368776c 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-UrlSeturl.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-UrlSeturl.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Url", - "value": "@url" + "value": "=@url" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-UtterancepropertySetutterance.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-UtterancepropertySetutterance.dialog index 10eb408f69..49512b8ec7 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-UtterancepropertySetutterance.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-UtterancepropertySetutterance.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Utteranceproperty", - "value": "@utterance" + "value": "=@utterance" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ZipcodepatternSetnumber.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ZipcodepatternSetnumber.dialog index 453b5fbcec..15eb6d0e59 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ZipcodepatternSetnumber.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ZipcodepatternSetnumber.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Zipcodepattern", - "value": "@number" + "value": "=@number" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ZipcodepatternSetutterance.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ZipcodepatternSetutterance.dialog index 1b6838e621..658df79ee1 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ZipcodepatternSetutterance.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/GeneratorTests/unittests/unittests-ZipcodepatternSetutterance.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Zipcodepattern", - "value": "@utterance" + "value": "=@utterance" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/MiscTests/Rule_Reprompt.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/MiscTests/Rule_Reprompt.test.dialog index 6ece5c2dda..6ec069935e 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/MiscTests/Rule_Reprompt.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/MiscTests/Rule_Reprompt.test.dialog @@ -53,7 +53,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.name", - "value": "@name" + "value": "=@name" } ] } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_ConditionalSelector.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_ConditionalSelector.test.dialog index a78a1c5ece..ddd6da6683 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_ConditionalSelector.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_ConditionalSelector.test.dialog @@ -10,7 +10,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.conditionalSelector", - "value": "true" + "value": "=true" } ] }, @@ -21,7 +21,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.conditionalSelector", - "value": "false" + "value": "=false" } ] }, diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_FirstSelector.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_FirstSelector.test.dialog index e396526f9f..0ac4b22495 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_FirstSelector.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_FirstSelector.test.dialog @@ -31,7 +31,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.a", - "value": "1" + "value": "=1" } ] }, @@ -42,7 +42,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.b", - "value": "1" + "value": "=1" } ] }, diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_MostSpecificFirstSelector.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_MostSpecificFirstSelector.test.dialog index 062c9cb175..e2c952c1b9 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_MostSpecificFirstSelector.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_MostSpecificFirstSelector.test.dialog @@ -31,7 +31,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.a", - "value": "1" + "value": "=1" } ] }, @@ -42,7 +42,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.b", - "value": "1" + "value": "=1" } ] }, diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_MostSpecificRandomSelector.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_MostSpecificRandomSelector.test.dialog index a540017055..6103385964 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_MostSpecificRandomSelector.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_MostSpecificRandomSelector.test.dialog @@ -7,17 +7,14 @@ "$kind": "Microsoft.RegexRecognizer", "intents": [ { - "intent": "a", "pattern": "a" }, { - "intent": "b", "pattern": "b" }, { - "intent": "trigger", "pattern": "trigger" } @@ -31,7 +28,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.a", - "value": "1" + "value": "=1" } ] }, @@ -42,7 +39,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.b", - "value": "1" + "value": "=1" } ] }, @@ -104,7 +101,6 @@ { "$kind": "Microsoft.OnIntent", "intent": "trigger", - "condition": "", "actions": [ { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_Priority.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_Priority.test.dialog index b8a48de7cd..62600b73c8 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_Priority.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_Priority.test.dialog @@ -25,14 +25,14 @@ { "$kind": "Microsoft.SetProperty", "property": "user.a", - "value": "1" + "value": "=1" } ] }, { "$kind": "Microsoft.OnIntent", "intent": "a", - "priority": "user.a + 1", + "priority": "=user.a + 1", "actions": [ { "$kind": "Microsoft.SendActivity", @@ -43,7 +43,7 @@ { "$kind": "Microsoft.OnIntent", "intent": "a", - "priority": "user.a", + "priority": "=user.a", "actions": [ { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_RandomSelector.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_RandomSelector.test.dialog index 2225816396..746ff9d5a5 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_RandomSelector.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_RandomSelector.test.dialog @@ -31,7 +31,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.a", - "value": "1" + "value": "=1" } ] }, @@ -42,7 +42,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.b", - "value": "1" + "value": "=1" } ] }, diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_RunOnce.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_RunOnce.test.dialog index c1fd582ace..f6a455b5ae 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_RunOnce.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SelectorTests/SelectorTests_RunOnce.test.dialog @@ -6,22 +6,18 @@ "$kind": "Microsoft.RegexRecognizer", "intents": [ { - "$kind": "Microsoft.IntentPattern", "intent": "a", "pattern": "a" }, { - "$kind": "Microsoft.IntentPattern", "intent": "b", "pattern": "b" }, { - "$kind": "Microsoft.IntentPattern", "intent": "c", "pattern": "c" }, { - "$kind": "Microsoft.IntentPattern", "intent": "trigger", "pattern": "trigger" } @@ -31,36 +27,33 @@ { "$kind": "Microsoft.OnIntent", "intent": "a", - "actions": [ { "$kind": "Microsoft.SetProperty", "property": "user.a", - "value": "1" + "value": "=1" } ] }, { "$kind": "Microsoft.OnIntent", "intent": "b", - "actions": [ { "$kind": "Microsoft.SetProperty", "property": "user.b", - "value": "1" + "value": "=1" } ] }, { "$kind": "Microsoft.OnIntent", "intent": "c", - "actions": [ { "$kind": "Microsoft.SetProperty", "property": "user.c", - "value": "1" + "value": "=1" } ] }, @@ -68,7 +61,6 @@ "$comment": "This will never fire since there are no memory references.", "$kind": "Microsoft.OnIntent", "intent": "trigger", - "runOnce": true, "actions": [ { @@ -80,8 +72,6 @@ { "$kind": "Microsoft.OnIntent", "intent": "trigger", - - "condition": "", "actions": [ { "$kind": "Microsoft.SendActivity", @@ -92,7 +82,6 @@ { "$kind": "Microsoft.OnIntent", "intent": "trigger", - "runOnce": true, "condition": "user.a == 1", "actions": [ @@ -105,7 +94,6 @@ { "$kind": "Microsoft.OnIntent", "intent": "trigger", - "runOnce": true, "condition": "user.a == 1 && user.b == 1", "actions": [ @@ -118,7 +106,6 @@ { "$kind": "Microsoft.OnIntent", "intent": "trigger", - "runOnce": true, "condition": "user.a == 1 || user.c == 1", "actions": [ diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SettingsStateTests/SettingsStateTests_TestTurnStateAcrossBoundaries.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SettingsStateTests/SettingsStateTests_TestTurnStateAcrossBoundaries.test.dialog index 476faca9f8..b6a5afadf1 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SettingsStateTests/SettingsStateTests_TestTurnStateAcrossBoundaries.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Tests/SettingsStateTests/SettingsStateTests_TestTurnStateAcrossBoundaries.test.dialog @@ -22,7 +22,7 @@ { "$kind": "Microsoft.SetProperty", "property": "dialog.name", - "value": "'foo'" + "value": "='foo'" }, { "$kind": "Microsoft.TextInput", diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests/ExpressionPropertyTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests/ExpressionPropertyTests.cs deleted file mode 100644 index 64182121d5..0000000000 --- a/tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests/ExpressionPropertyTests.cs +++ /dev/null @@ -1,149 +0,0 @@ -// Licensed under the MIT License. -// Copyright (c) Microsoft Corporation. All rights reserved. -#pragma warning disable SA1402 // File may only contain a single type -#pragma warning disable SA1649 // File name should match first type name - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Bot.Builder.Dialogs.Declarative.Converters; -using Microsoft.Bot.Builder.Dialogs.Declarative.Resources; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace Microsoft.Bot.Builder.Dialogs.Declarative.Tests -{ - public class Bar - { - public Bar() - { - } - - public ExpressionProperty Foo { get; set; } - } - - public class Foo - { - public Foo() - { - } - - public string Name { get; set; } - - public int Age { get; set; } - } - - [TestClass] - public class ExpressionPropertyTests - { - public TestContext TestContext { get; set; } - - [TestMethod] - public void TestExpressionAccess() - { - var state = new - { - test = new Foo() - { - Name = "Test", - Age = 22 - } - }; - - var ep = new ExpressionProperty("test"); - var result = ep.GetValue(state); - Assert.AreEqual("Test", result.Name); - Assert.AreEqual(22, result.Age); - } - - [TestMethod] - public void TestValueAccess() - { - var foo = new Foo() - { - Name = "Test", - Age = 22 - }; - - var ep = new ExpressionProperty(foo); - var result = ep.GetValue(new object()); - Assert.AreEqual("Test", result.Name); - Assert.AreEqual(22, result.Age); - } - - [TestMethod] - public void TestJObjectAccess() - { - var foo = new Foo() - { - Name = "Test", - Age = 22 - }; - - var ep = new ExpressionProperty(JObject.FromObject(foo)); - var result = ep.GetValue(new object()); - Assert.AreEqual("Test", result.Name); - Assert.AreEqual(22, result.Age); - } - - [TestMethod] - public void TestConverterExpressionAccess() - { - var state = new - { - test = new Foo() - { - Name = "Test", - Age = 22 - } - }; - - var json = JsonConvert.SerializeObject(new - { - Foo = "test" - }); - var settings = new JsonSerializerSettings() - { - Converters = new List() { new ExpressionPropertyConverter>() } - }; - - var bar = JsonConvert.DeserializeObject(json, settings); - Assert.AreEqual(typeof(Bar), bar.GetType()); - Assert.AreEqual(typeof(ExpressionProperty), bar.Foo.GetType()); - var foo = bar.Foo.GetValue(state); - Assert.AreEqual("Test", foo.Name); - Assert.AreEqual(22, foo.Age); - } - - [TestMethod] - public void TestConverterObjectAccess() - { - var state = new - { - }; - - var json = JsonConvert.SerializeObject(new - { - Foo = new - { - Name = "Test", - Age = 22 - } - }); - var settings = new JsonSerializerSettings() - { - Converters = new List() { new ExpressionPropertyConverter>() } - }; - - var bar = JsonConvert.DeserializeObject(json, settings); - Assert.AreEqual(typeof(Bar), bar.GetType()); - Assert.AreEqual(typeof(ExpressionProperty), bar.Foo.GetType()); - var foo = bar.Foo.GetValue(state); - Assert.AreEqual("Test", foo.Name); - Assert.AreEqual(22, foo.Age); - } - } -} diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests/JsonLoadTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests/JsonLoadTests.cs index 631e6cfbf7..967d5bceec 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests/JsonLoadTests.cs +++ b/tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests/JsonLoadTests.cs @@ -438,7 +438,7 @@ private TestAdapter InitializeAdapter(bool sendTrace = false) .UseResourceExplorer(resourceExplorer) .UseAdaptiveDialogs() .UseLanguageGeneration(resourceExplorer) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); return adapter; } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/AttachmentPromptTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Tests/AttachmentPromptTests.cs index 539fc6b4ed..275c8ee57d 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/AttachmentPromptTests.cs +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/AttachmentPromptTests.cs @@ -40,7 +40,7 @@ public async Task BasicAttachmentPrompt() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); // Create new DialogSet. var dialogs = new DialogSet(dialogState); @@ -87,7 +87,7 @@ public async Task RetryAttachmentPrompt() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); // Create new DialogSet. var dialogs = new DialogSet(dialogState); diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/ComponentDialogTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Tests/ComponentDialogTests.cs index 3c4117dd10..82a8732250 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/ComponentDialogTests.cs +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/ComponentDialogTests.cs @@ -26,7 +26,7 @@ public async Task CallDialogInParentComponent() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); await new TestFlow(adapter, async (turnContext, cancellationToken) => { @@ -91,7 +91,7 @@ public async Task BasicWaterfallTest() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); await new TestFlow(adapter, async (turnContext, cancellationToken) => { @@ -198,7 +198,7 @@ public async Task BasicComponentDialogTest() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); await new TestFlow(adapter, async (turnContext, cancellationToken) => { @@ -238,7 +238,7 @@ public async Task NestedComponentDialogTest() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); await new TestFlow(adapter, async (turnContext, cancellationToken) => { diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/ConfirmPromptTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Tests/ConfirmPromptTests.cs index fb6f2db475..5588d4ba6f 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/ConfirmPromptTests.cs +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/ConfirmPromptTests.cs @@ -42,7 +42,7 @@ public async Task ConfirmPrompt() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); // Create new DialogSet. var dialogs = new DialogSet(dialogState); @@ -84,7 +84,7 @@ public async Task ConfirmPromptRetry() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var dialogs = new DialogSet(dialogState); dialogs.Add(new ConfirmPrompt("ConfirmPrompt", defaultLocale: Culture.English)); @@ -140,7 +140,7 @@ public async Task ConfirmPromptNoOptions() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var dialogs = new DialogSet(dialogState); dialogs.Add(new ConfirmPrompt("ConfirmPrompt", defaultLocale: Culture.English)); @@ -184,7 +184,7 @@ public async Task ConfirmPromptChoiceOptionsNumbers() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var dialogs = new DialogSet(dialogState); var prompt = new ConfirmPrompt("ConfirmPrompt", defaultLocale: Culture.English); @@ -245,7 +245,7 @@ public async Task ConfirmPromptChoiceOptionsMultipleAttempts() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var dialogs = new DialogSet(dialogState); var prompt = new ConfirmPrompt("ConfirmPrompt", defaultLocale: Culture.English); @@ -308,7 +308,7 @@ public async Task ConfirmPromptChoiceOptionsNoNumbers() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var dialogs = new DialogSet(dialogState); var prompt = new ConfirmPrompt("ConfirmPrompt", defaultLocale: Culture.English); diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/DateTimePromptTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Tests/DateTimePromptTests.cs index 657e5dc929..07c7b498fc 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/DateTimePromptTests.cs +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/DateTimePromptTests.cs @@ -26,7 +26,7 @@ public async Task BasicDateTimePrompt() TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); // Create new DialogSet. var dialogs = new DialogSet(dialogState); @@ -67,7 +67,7 @@ public async Task MultipleResolutionsDateTimePrompt() TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); // Create new DialogSet. var dialogs = new DialogSet(dialogState); @@ -110,7 +110,7 @@ public async Task DateTimePromptWithValidator() TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); // Create new DialogSet. var dialogs = new DialogSet(dialogState); diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/DialogManagerTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Tests/DialogManagerTests.cs index 1a7a29af89..1c7e114d24 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/DialogManagerTests.cs +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/DialogManagerTests.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#pragma warning disable SA1402 // File may only contain a single type using System; using System.Collections.Generic; @@ -8,6 +9,8 @@ using System.Threading.Tasks; using Microsoft.Bot.Builder.Adapters; using Microsoft.Bot.Builder.Dialogs.Adaptive; +using Microsoft.Bot.Builder.Dialogs.Adaptive.Actions; +using Microsoft.Bot.Builder.Dialogs.Adaptive.Conditions; using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing; using Microsoft.Bot.Schema; using Microsoft.Extensions.Configuration; @@ -127,6 +130,58 @@ public async Task DialogManager_OnErrorEvent_Root() await TestUtilities.RunTestScript(); } + [TestMethod] + public async Task DialogManager_DialogSet() + { + var storage = new MemoryStorage(); + var convoState = new ConversationState(storage); + var userState = new UserState(storage); + + var adapter = new TestAdapter(); + adapter + .UseStorage(storage) + .UseState(userState, convoState) + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); + + var rootDialog = new AdaptiveDialog() + { + Triggers = new List() + { + new OnBeginDialog() + { + Actions = new List() + { + new SetProperty() + { + Property = "conversation.dialogId", + Value = "test" + }, + new BeginDialog() + { + Dialog = "=conversation.dialogId" + }, + new BeginDialog() + { + Dialog = "test" + } + } + } + } + }; + + DialogManager dm = new DialogManager(rootDialog); + dm.Dialogs.Add(new SimpleDialog() { Id = "test" }); + + await new TestFlow(adapter, async (turnContext, cancellationToken) => + { + await dm.OnTurnAsync(turnContext, cancellationToken: cancellationToken).ConfigureAwait(false); + }) + .SendConversationUpdate() + .AssertReply("simple") + .AssertReply("simple") + .StartTestAsync(); + } + private Dialog CreateTestDialog(string property = "user.name") { return new AskForNameDialog(property.Replace(".", string.Empty), property); @@ -141,7 +196,7 @@ private TestFlow CreateFlow(Dialog dialog, IStorage storage, string conversation adapter .UseStorage(storage) .UseState(userState, convoState) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); DialogManager dm = new DialogManager(dialog); return new TestFlow(adapter, async (turnContext, cancellationToken) => @@ -192,5 +247,14 @@ public override async Task ResumeDialogAsync(DialogContext out return await outerDc.EndDialogAsync(result); } } + + public class SimpleDialog : Dialog + { + public async override Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default) + { + await dc.Context.SendActivityAsync("simple"); + return await dc.EndDialogAsync(); + } + } } } diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/DialogStateManagerTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Tests/DialogStateManagerTests.cs index 1615d0769d..daf741c943 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/DialogStateManagerTests.cs +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/DialogStateManagerTests.cs @@ -578,7 +578,8 @@ internal class TestDialog : Dialog { public override Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default) { - dc.Context.SendActivityAsync(dc.GetState().GetValue("conversation.test", () => "unknown")); + var data = dc.GetState().GetValue("conversation.test", () => "unknown"); + dc.Context.SendActivityAsync(data); dc.GetState().SetValue("conversation.test", "havedata"); return Task.FromResult(new DialogTurnResult(DialogTurnStatus.Waiting)); } @@ -593,7 +594,8 @@ public override Task ContinueDialogAsync(DialogContext dc, Can return dc.EndDialogAsync(); } - dc.Context.SendActivityAsync(dc.GetState().GetValue("conversation.test", () => "unknown")); + var data = dc.GetState().GetValue("conversation.test", () => "unknown"); + dc.Context.SendActivityAsync(data); return Task.FromResult(new DialogTurnResult(DialogTurnStatus.Waiting)); } } @@ -607,7 +609,9 @@ public async Task TestConversationResetOnException() var adapter = new TestAdapter() .UseStorage(storage) - .UseState(userState, conversationState); + .UseState(userState, conversationState) + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); + adapter.OnTurnError = async (context, exception) => { await conversationState.DeleteAsync(context); @@ -620,15 +624,15 @@ public async Task TestConversationResetOnException() { return dm.OnTurnAsync(turnContext, cancellationToken: cancellationToken); }) - .Send("yo") + .Send("yo1") .AssertReply("unknown") - .Send("yo") + .Send("yo2") .AssertReply("havedata") .Send("throw") .AssertReply("throwing") - .Send("yo") + .Send("yo3") .AssertReply("unknown") - .Send("yo") + .Send("yo4") .AssertReply("havedata") .StartTestAsync(); } @@ -705,7 +709,7 @@ private TestFlow CreateFlow(Dialog dialog, ConversationState convoState = null, var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName), sendTrace) .Use(new RegisterClassMiddleware(new MemoryStorage())) .UseState(new UserState(new MemoryStorage()), convoState ?? new ConversationState(new MemoryStorage())) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var dm = new DialogManager(dialog); diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/MemoryScopeTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Tests/MemoryScopeTests.cs index 1ee1ad46f0..4f3c92c1e8 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/MemoryScopeTests.cs +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/MemoryScopeTests.cs @@ -71,7 +71,7 @@ public async Task DialogMemoryScopeTest() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .UseStorage(storage) .UseState(new UserState(storage), new ConversationState(storage)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); DialogManager dm = new DialogManager(new MemoryScopeTestDialog()); @@ -96,7 +96,7 @@ public async Task SettingsMemoryScopeTest() .UseStorage(storage) .Use(new RegisterClassMiddleware(configuration)) .UseState(new UserState(storage), new ConversationState(storage)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); DialogManager dm = new DialogManager(new SettingsScopeTestDialog()); @@ -138,7 +138,7 @@ public async Task TestPathResolvers() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .UseStorage(storage) .UseState(new UserState(storage), new ConversationState(storage)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); DialogManager dm = new DialogManager(new PathResolverTestDialog()); diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Leaf.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Leaf.test.dialog index bfabb0f24b..10bc88ef23 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Leaf.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Leaf.test.dialog @@ -40,7 +40,7 @@ "actions": [ { "$kind": "Microsoft.SetProperty", - "property": "user.foo", + "property": "foo", "value": "xxx" } ] diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Parent.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Parent.test.dialog index 3896107b2b..21e3a7805f 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Parent.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Parent.test.dialog @@ -42,7 +42,7 @@ "actions": [ { "$kind": "Microsoft.SetProperty", - "property": "user.foo", + "property": "foo", "value": "xxx" } ] diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Root.test.dialog b/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Root.test.dialog index c092ec4027..49b41f0653 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Root.test.dialog +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/Tests/DialogManagerTests/DialogManager_OnErrorEvent_Root.test.dialog @@ -42,7 +42,7 @@ "actions": [ { "$kind": "Microsoft.SetProperty", - "property": "user.foo", + "property": "foo", "value": "xxx" } ] diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/TextPromptTests.cs b/tests/Microsoft.Bot.Builder.Dialogs.Tests/TextPromptTests.cs index 822907f249..5b324e0338 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/TextPromptTests.cs +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/TextPromptTests.cs @@ -39,7 +39,7 @@ public async Task TextPrompt() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var dialogs = new DialogSet(dialogState); @@ -77,7 +77,7 @@ public async Task TextPromptValidator() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var dialogs = new DialogSet(dialogState); @@ -131,7 +131,7 @@ public async Task TextPromptWithRetryPrompt() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var dialogs = new DialogSet(dialogState); @@ -185,7 +185,7 @@ public async Task TextPromptValidatorWithMessageShouldNotSendRetryPrompt() var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) .Use(new AutoSaveStateMiddleware(convoState)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var dialogs = new DialogSet(dialogState); diff --git a/tests/Microsoft.Bot.Builder.TemplateManager/TemplateManagerTests.cs b/tests/Microsoft.Bot.Builder.TemplateManager/TemplateManagerTests.cs index 52cf09518e..7666095140 100644 --- a/tests/Microsoft.Bot.Builder.TemplateManager/TemplateManagerTests.cs +++ b/tests/Microsoft.Bot.Builder.TemplateManager/TemplateManagerTests.cs @@ -110,7 +110,7 @@ public async Task DictionaryTemplateEngine_SimpleActivityBinding() public async Task TemplateManager_defaultlookup() { TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var templateManager = new TemplateManager() .Register(new DictionaryRenderer(templates1)) @@ -130,7 +130,7 @@ public async Task TemplateManager_defaultlookup() public async Task TemplateManager_DataDefined() { TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var templateManager = new TemplateManager() { @@ -155,7 +155,7 @@ public async Task TemplateManager_DataDefined() public async Task TemplateManager_enLookup() { TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var templateManager = new TemplateManager() .Register(new DictionaryRenderer(templates1)) @@ -176,7 +176,7 @@ public async Task TemplateManager_enLookup() public async Task TemplateManager_frLookup() { TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var templateManager = new TemplateManager() .Register(new DictionaryRenderer(templates1)) @@ -197,7 +197,7 @@ public async Task TemplateManager_frLookup() public async Task TemplateManager_override() { TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var templateManager = new TemplateManager() .Register(new DictionaryRenderer(templates1)) @@ -218,7 +218,7 @@ public async Task TemplateManager_override() public async Task TemplateManager_useTemplateEngine() { TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)) - .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger())); + .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false))); var templateManager = new TemplateManager() .Register(new DictionaryRenderer(templates1)) diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/CustomSteps/JavascriptAction.cs b/tests/Microsoft.Bot.Builder.TestBot.Json/CustomSteps/JavascriptAction.cs index 074423b9d6..24715353ea 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/CustomSteps/JavascriptAction.cs +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/CustomSteps/JavascriptAction.cs @@ -50,9 +50,11 @@ public string Script public override Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { + var dcState = dc.GetState(); + // map state into json dynamic payload = new JObject(); - payload.state = dc.GetState().GetMemorySnapshot(); + payload.state = dcState.GetMemorySnapshot(); // payload.property = (this.Property != null) ? dc.GetValue(this.Property) : null; string payloadJson = JsonConvert.SerializeObject(payload); @@ -61,10 +63,10 @@ public string Script if (!string.IsNullOrEmpty(responseJson)) { dynamic response = JsonConvert.DeserializeObject(responseJson); - dc.GetState().SetValue(ScopePath.USER, response.state.user); - dc.GetState().SetValue(ScopePath.CONVERSATION, response.state.conversation); - dc.GetState().SetValue(ScopePath.DIALOG, response.state.dialog); - dc.GetState().SetValue(ScopePath.TURN, response.state.turn); + dcState.SetValue(ScopePath.USER, response.state.user); + dcState.SetValue(ScopePath.CONVERSATION, response.state.conversation); + dcState.SetValue(ScopePath.DIALOG, response.state.dialog); + dcState.SetValue(ScopePath.TURN, response.state.turn); return dc.EndDialogAsync((object)response.result, cancellationToken: cancellationToken); } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/03 - IfCondition/SwitchCondition.main.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/03 - IfCondition/SwitchCondition.main.dialog index 682fadc650..021c020878 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/03 - IfCondition/SwitchCondition.main.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/03 - IfCondition/SwitchCondition.main.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.age", - "value": "22" + "value": "=22" }, { "$kind": "Microsoft.SwitchCondition", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/04 - TextInput/TextInput.main.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/04 - TextInput/TextInput.main.dialog index 385e41f147..d2d010b6b1 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/04 - TextInput/TextInput.main.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/04 - TextInput/TextInput.main.dialog @@ -5,7 +5,6 @@ "$kind": "Microsoft.RegexRecognizer", "intents": [ { - "intent": "Cancel", "pattern": "(?i)cancel" } @@ -23,7 +22,7 @@ "$kind": "Microsoft.TextInput", "property": "user.name", "prompt": "Hello, I'm Zoidberg. What is your name?", - "outputFormat": "trim(this.value)", + "outputFormat": "=trim(this.value)", "allowInterruptions": "true" } ] @@ -40,7 +39,7 @@ "$kind": "Microsoft.TextInput", "property": "user.name2", "prompt": "Hello, I'm Zoidberg. What is your name?", - "outputFormat": "trim(this.value)", + "outputFormat": "=trim(this.value)", "allowInterruptions": "!#Cancel" } ] diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/11 - HttpRequest/HttpRequest.main.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/11 - HttpRequest/HttpRequest.main.dialog index 0323b8df31..e5e0b4a1ec 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/11 - HttpRequest/HttpRequest.main.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/11 - HttpRequest/HttpRequest.main.dialog @@ -34,7 +34,7 @@ "id": 0, "name": "string" }, - "name": "@{dialog.petname}", + "name": "=dialog.petname", "photoUrls": [ "string" ], diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/14 - RepeatDialog/RepeatDialog.main.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/14 - RepeatDialog/RepeatDialog.main.dialog index 4d1cccbf3c..ace1979b01 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/14 - RepeatDialog/RepeatDialog.main.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/14 - RepeatDialog/RepeatDialog.main.dialog @@ -5,8 +5,6 @@ "$kind": "Microsoft.RegexRecognizer", "intents": [ { - - "intent": "cancel", "pattern": "cancel" } @@ -24,7 +22,7 @@ "$kind": "Microsoft.TextInput", "prompt": "Hello, what is your name?", "property": "user.name", - "value": "user.name" + "value": "=user.name" }, { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/15 - TraceAndLog/TraceAndLog.main.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/15 - TraceAndLog/TraceAndLog.main.dialog index cb22395798..1929a03a69 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/15 - TraceAndLog/TraceAndLog.main.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/15 - TraceAndLog/TraceAndLog.main.dialog @@ -13,7 +13,7 @@ { "$kind": "Microsoft.TraceActivity", "valueType": "memory", - "value": "user" + "value": "=user" }, { "$kind": "Microsoft.LogAction", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/CalendarClearUserData.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/CalendarClearUserData.dialog index 0307a3b535..b793b2f7d5 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/CalendarClearUserData.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/CalendarClearUserData.dialog @@ -1,92 +1,81 @@ { - "$schema": "../../app.schema", - "$kind": "Microsoft.AdaptiveDialog", - "triggers": [ - { - "$kind": "Microsoft.OnBeginDialog", - "actions": [ - // Reset data - { - "$kind": "Microsoft.SetProperty", - "value": "'msgraph'", - "property": "user.provider" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "3", - "property": "user.pageSize" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "0", - "property": "user.showIndex" - }, - { - "$kind": "Microsoft.SetProperty", - "property": "user.focusedMeeting", - "value": "null" - }, - { - "$kind": "Microsoft.EditArray", - "changeType": "clear", - "itemsProperty": "user.meetings" - }, - { - "$kind": "Microsoft.EditArray", - "changeType": "clear", - "itemsProperty": "user.attendees" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "null", - "property": "user.meeting" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "null", - "property": "user.subject" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "null", - "property": "user.body" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "null", - "property": "user.email" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "null", - "property": "user.startDate" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "null", - "property": "user.startTime" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "null", - "property": "user.startDateTime" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "null", - "property": "user.endDateTime" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "null", - "property": "user.duration" - }, - { - "$kind": "Microsoft.SetProperty", - "value": "null", - "property": "user.location" + "$schema": "../../app.schema", + "$kind": "Microsoft.AdaptiveDialog", + "triggers": [ + { + "$kind": "Microsoft.OnBeginDialog", + "actions": [ + // Reset data + { + "$kind": "Microsoft.SetProperty", + "value": "='msgraph'", + "property": "user.provider" + }, + { + "$kind": "Microsoft.SetProperty", + "value": "=3", + "property": "user.pageSize" + }, + { + "$kind": "Microsoft.SetProperty", + "value": "=0", + "property": "user.showIndex" + }, + { + "$kind": "Microsoft.DeleteProperty", + "property": "user.focusedMeeting" + }, + { + "$kind": "Microsoft.EditArray", + "changeType": "clear", + "itemsProperty": "user.meetings" + }, + { + "$kind": "Microsoft.EditArray", + "changeType": "clear", + "itemsProperty": "user.attendees" + }, + { + "$kind": "Microsoft.DeleteProperty", + "property": "user.meeting" + }, + { + "$kind": "Microsoft.DeleteProperty", + "property": "user.subject" + }, + { + "$kind": "Microsoft.DeleteProperty", + "property": "user.body" + }, + { + "$kind": "Microsoft.DeleteProperty", + "property": "user.email" + }, + { + "$kind": "Microsoft.DeleteProperty", + "property": "user.startDate" + }, + { + "$kind": "Microsoft.DeleteProperty", + "property": "user.startTime" + }, + { + "$kind": "Microsoft.DeleteProperty", + "property": "user.startDateTime" + }, + { + "$kind": "Microsoft.DeleteProperty", + "property": "user.endDateTime" + }, + { + "$kind": "Microsoft.DeleteProperty", + "property": "user.duration" + }, + { + "$kind": "Microsoft.DeleteProperty", + "property": "user.location" + } + ] } - ] - } - ] + ] } \ No newline at end of file diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/CalendarNextPage.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/CalendarNextPage.dialog index 0671cf7de6..5e2ff69363 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/CalendarNextPage.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/CalendarNextPage.dialog @@ -7,7 +7,7 @@ "actions": [ { "$kind": "Microsoft.SetProperty", - "value": "user.showIndex + 1", + "value": "=user.showIndex + 1", "property": "user.showIndex" } ] diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/GetNewEndDateTime.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/GetNewEndDateTime.dialog index 9dc54151dd..c547eb5d2b 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/GetNewEndDateTime.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Controller/GetNewEndDateTime.dialog @@ -14,7 +14,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.endDateTime", - "value": "addSeconds(user.startDateTime[0].Value, user.duration)" + "value": "=addSeconds(user.startDateTime[0].Value, user.duration)" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/AcceptMeeting/AcceptMeeting.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/AcceptMeeting/AcceptMeeting.dialog index 6994542d1b..4555eea3c6 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/AcceptMeeting/AcceptMeeting.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/AcceptMeeting/AcceptMeeting.dialog @@ -26,7 +26,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[0]" + "value": "=user.meetings[0]" } ] }, @@ -37,7 +37,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[1]" + "value": "=user.meetings[1]" } ] }, @@ -48,7 +48,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[2]" + "value": "=user.meetings[2]" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/CreateMeeting/CreateMeeting.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/CreateMeeting/CreateMeeting.dialog index 42bf08df8c..f5f72a4d11 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/CreateMeeting/CreateMeeting.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/CreateMeeting/CreateMeeting.dialog @@ -42,7 +42,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.startDate", - "value": "formatDateTime(user.startDate[0].Value, 'yyyy-MM-dd')" + "value": "=formatDateTime(user.startDate[0].Value, 'yyyy-MM-dd')" }, { "$kind": "Microsoft.IfCondition", @@ -58,12 +58,12 @@ { "$kind": "Microsoft.SetProperty", "property": "user.startTime", - "value": "formatDateTime(user.startTime[0].Value, 'THH:mm:ssZ')" + "value": "=formatDateTime(user.startTime[0].Value, 'THH:mm:ssZ')" }, { "$kind": "Microsoft.SetProperty", "property": "user.startDateTime", - "value": "formatDateTime(concat(user.startDate, user.startTime))" + "value": "=formatDateTime(concat(user.startDate, user.startTime))" }, { "$kind": "Microsoft.IfCondition", @@ -79,7 +79,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.endDateTime", - "value": "addSeconds(user.startDateTime, int(user.duration[0].Value))" + "value": "=addSeconds(user.startDateTime, int(user.duration[0].Value))" }, { "$kind": "Microsoft.IfCondition", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/DeclineMeeting/DeclineMeeting.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/DeclineMeeting/DeclineMeeting.dialog index a199d40c59..cefc69628c 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/DeclineMeeting/DeclineMeeting.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/DeclineMeeting/DeclineMeeting.dialog @@ -26,7 +26,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[0]" + "value": "=user.meetings[0]" } ] }, @@ -37,7 +37,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[1]" + "value": "=user.meetings[1]" } ] }, @@ -48,7 +48,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[2]" + "value": "=user.meetings[2]" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/ShowMeeting/ShowMeeting.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/ShowMeeting/ShowMeeting.dialog index a85af521b9..1721d87431 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/ShowMeeting/ShowMeeting.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/ShowMeeting/ShowMeeting.dialog @@ -65,7 +65,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[0]" + "value": "=user.meetings[0]" } ] }, @@ -76,7 +76,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[1]" + "value": "=user.meetings[1]" } ] }, @@ -87,7 +87,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[2]" + "value": "=user.meetings[2]" } ] }, diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/UpdateMeeting/UpdateMeeting.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/UpdateMeeting/UpdateMeeting.dialog index 3a904b7c57..64ce243a24 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/UpdateMeeting/UpdateMeeting.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Dialog/UpdateMeeting/UpdateMeeting.dialog @@ -26,7 +26,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[0]" + "value": "=user.meetings[0]" } ] }, @@ -37,7 +37,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[1]" + "value": "=user.meetings[1]" } ] }, @@ -48,7 +48,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedMeeting", - "value": "user.meetings[2]" + "value": "=user.meetings[2]" } ] } @@ -81,12 +81,12 @@ { "$kind": "Microsoft.SetProperty", "property": "user.startDateTime", - "value": "formatDateTime(user.startDateTime[0].Value)" + "value": "=formatDateTime(user.startDateTime[0].Value)" }, { "$kind": "Microsoft.SetProperty", "property": "user.endDateTime", - "value": "formatDateTime(user.endDateTime[0].Value)" + "value": "=formatDateTime(user.endDateTime[0].Value)" }, { "$kind": "Microsoft.ConfirmInput", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Service/MSGraph/GetContactService.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Service/MSGraph/GetContactService.dialog index d352b1864e..b8c55f74fa 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Service/MSGraph/GetContactService.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/CalendarBot/Service/MSGraph/GetContactService.dialog @@ -33,7 +33,7 @@ }, { "$kind": "Microsoft.SetProperty", - "value": "dialog.getResponse.content.value[0].emailAddresses[0].address", + "value": "=dialog.getResponse.content.value[0].emailAddresses[0].address", "property": "user.email" } ] diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/ClearUserData.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/ClearUserData.dialog index 5371623162..d560d63b91 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/ClearUserData.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/ClearUserData.dialog @@ -5,23 +5,23 @@ // Reset data { "$kind": "Microsoft.SetProperty", - "value": "'msgraph'", + "value": "msgraph", "property": "user.mailType" }, { "$kind": "Microsoft.SetProperty", - "value": "3", + "value": "=3", "property": "user.pageSize" }, { "$kind": "Microsoft.SetProperty", - "value": "0", + "value": "=0", "property": "user.showIndex" }, { "$kind": "Microsoft.SetProperty", "property": "user.emailCount", - "value": "0" + "value": "=0" }, { "$kind": "Microsoft.DeleteProperty", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/GetDisplayEmails.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/GetDisplayEmails.dialog index 57895eea4c..a72a739599 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/GetDisplayEmails.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/GetDisplayEmails.dialog @@ -11,7 +11,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.emailCount", - "value": "count(user.getGraphEmails.value)" + "value": "=count(user.getGraphEmails.value)" }, // *** Translate from graph model to view model. Map the same entity from graph/google to the same attribute. *** { diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/NextPage.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/NextPage.dialog index f5377f134f..bb0a131811 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/NextPage.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Controller/NextPage.dialog @@ -5,7 +5,7 @@ // Todo: check page boundary. { "$kind": "Microsoft.SetProperty", - "value": "user.showIndex+1", + "value": "=user.showIndex+1", "property": "user.showIndex" } ] diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ForwardEmail/ForwardEmail.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ForwardEmail/ForwardEmail.dialog index 9739291517..2246ee50f5 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ForwardEmail/ForwardEmail.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ForwardEmail/ForwardEmail.dialog @@ -12,7 +12,7 @@ }, { "$kind": "Microsoft.SetProperty", - "value": "concat('Fw:',user.focusedEmail.subject)", + "value": "=concat('Fw:',user.focusedEmail.subject)", "property": "user.fwSubject" }, { diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ReplyEmail/ReplyEmail.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ReplyEmail/ReplyEmail.dialog index e0e91e45ed..f0f8247543 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ReplyEmail/ReplyEmail.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ReplyEmail/ReplyEmail.dialog @@ -12,7 +12,7 @@ }, { "$kind": "Microsoft.SetProperty", - "value": "concat('Re:',user.focusedEmail.subject)", + "value": "=concat('Re:',user.focusedEmail.subject)", "property": "user.toSubject" }, { diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/Shared/ChooseEmail.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/Shared/ChooseEmail.dialog index c2dc08cc45..c8565d4b60 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/Shared/ChooseEmail.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/Shared/ChooseEmail.dialog @@ -19,7 +19,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedEmail", - "value": "user.emails[0]" + "value": "=user.emails[0]" } ] }, @@ -30,7 +30,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedEmail", - "value": "user.emails[1]" + "value": "=user.emails[1]" } ] }, @@ -41,7 +41,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedEmail", - "value": "user.emails[2]" + "value": "=user.emails[2]" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ShowEmail/DisplayEmailList.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ShowEmail/DisplayEmailList.dialog index e96a94cd0a..cb006fad59 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ShowEmail/DisplayEmailList.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Dialogs/ShowEmail/DisplayEmailList.dialog @@ -32,7 +32,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedEmail", - "value": "user.emails[0]" + "value": "=user.emails[0]" } ] }, @@ -43,7 +43,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedEmail", - "value": "user.emails[1]" + "value": "=user.emails[1]" } ] }, @@ -54,7 +54,7 @@ { "$kind": "Microsoft.SetProperty", "property": "user.focusedEmail", - "value": "user.emails[2]" + "value": "=user.emails[2]" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Service/MSGraph/GetContact.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Service/MSGraph/GetContact.dialog index 31eeb1e96a..899e4ea57f 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Service/MSGraph/GetContact.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/EmailBot/Service/MSGraph/GetContact.dialog @@ -30,7 +30,7 @@ }, { "$kind": "Microsoft.SetProperty", - "value": "dialog.getResponse.content.value[0].emailAddresses[0].address", + "value": "=dialog.getResponse.content.value[0].emailAddresses[0].address", "property": "user.email" } ] diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-BreadSetBreadEntity.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-BreadSetBreadEntity.dialog index 1dcbb3cc3c..1f21481142 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-BreadSetBreadEntity.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-BreadSetBreadEntity.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Bread", - "value": "@BreadEntity" + "value": "=@BreadEntity" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CancelConfirmationSet.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CancelConfirmationSet.dialog index 438f626d96..dc7aef0705 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CancelConfirmationSet.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CancelConfirmationSet.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$CancelConfirmation", - "value": "@Confirmation" + "value": "=@Confirmation" }, { "$kind": "Microsoft.IfCondition", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-ChangePropertyConfirmationSet.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-ChangePropertyConfirmationSet.dialog index 25ba492765..d7c656766d 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-ChangePropertyConfirmationSet.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-ChangePropertyConfirmationSet.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$ChangePropertyConfirmation", - "value": "@Confirmation" + "value": "=@Confirmation" }, { "$kind": "Microsoft.IfCondition", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CheeseSetCheeseEntity.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CheeseSetCheeseEntity.dialog index 06be0d2356..8534be2036 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CheeseSetCheeseEntity.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CheeseSetCheeseEntity.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Cheese", - "value": "@CheeseEntity" + "value": "=@CheeseEntity" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CompleteSetConfirmation.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CompleteSetConfirmation.dialog index 151eb7dd6d..f5f05690c9 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CompleteSetConfirmation.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-CompleteSetConfirmation.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$CompleteConfirmation", - "value": "@Confirmation" + "value": "=@Confirmation" }, { "$kind": "Microsoft.IfCondition", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-LengthSetdimension.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-LengthSetdimension.dialog index 0f9a187eda..3817d51617 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-LengthSetdimension.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-LengthSetdimension.dialog @@ -12,12 +12,12 @@ { "$kind": "Microsoft.SetProperty", "property": "$Length.number", - "value": "@dimension.number" + "value": "=@dimension.number" }, { "$kind": "Microsoft.SetProperty", "property": "$Length.units", - "value": "@dimension.units" + "value": "=@dimension.units" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-MeatSetMeatEntity.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-MeatSetMeatEntity.dialog index d703491117..8ad2ba8ce2 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-MeatSetMeatEntity.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-MeatSetMeatEntity.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Meat", - "value": "@MeatEntity" + "value": "=@MeatEntity" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-NameSetpersonName.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-NameSetpersonName.dialog index c057782bac..f90bd964f2 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-NameSetpersonName.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-NameSetpersonName.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Name", - "value": "@personName" + "value": "=@personName" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-NameSetutterance.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-NameSetutterance.dialog index 3a40e70b80..e9fd37aa72 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-NameSetutterance.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-NameSetutterance.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Name", - "value": "@utterance" + "value": "=@utterance" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-PriceSetmoney.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-PriceSetmoney.dialog index 38dbde0ea8..00c54dc83f 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-PriceSetmoney.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-PriceSetmoney.dialog @@ -12,12 +12,12 @@ { "$kind": "Microsoft.SetProperty", "property": "$Price.number", - "value": "@money.number" + "value": "=@money.number" }, { "$kind": "Microsoft.SetProperty", "property": "$Price.units", - "value": "@money.units" + "value": "=@money.units" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-PropertyToRememberSet.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-PropertyToRememberSet.dialog index 3b5da03f65..0b51a7539b 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-PropertyToRememberSet.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-PropertyToRememberSet.dialog @@ -8,7 +8,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$PropertyToRemember", - "value": "@PROPERTYName" + "value": "=@PROPERTYName" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-QuantitySetnumber.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-QuantitySetnumber.dialog index b4cc4d2c8c..7a8432f014 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-QuantitySetnumber.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-QuantitySetnumber.dialog @@ -12,7 +12,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$Quantity", - "value": "@number" + "value": "=@number" } ] } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-ReadPropertyIntent.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-ReadPropertyIntent.dialog index 8aa2bd366e..387b62db81 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-ReadPropertyIntent.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/GeneratedForm/sandwich-ReadPropertyIntent.dialog @@ -11,7 +11,7 @@ { "$kind": "Microsoft.SetProperty", "property": "$PropertyToRemember", - "value": "@PROPERTYName" + "value": "=@PROPERTYName" }, { "$kind": "Microsoft.Ask", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/AddToDo.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/AddToDo.dialog index 3052251cd3..f21f5111a9 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/AddToDo.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/AddToDo.dialog @@ -8,8 +8,8 @@ "actions": [ { "$kind": "Microsoft.SetProperty", - "value": "@title", - "property": "dialog.todo" + "property": "dialog.todo", + "value": "=@title" }, { "$kind": "Microsoft.TextInput", @@ -31,7 +31,7 @@ "$kind": "Microsoft.EditArray", "changeType": "push", "itemsProperty": "user.todos", - "value": "dialog.todo" + "value": "=dialog.todo" }, { "$kind": "Microsoft.SendActivity", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/DeleteToDo.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/DeleteToDo.dialog index 7525a91bda..7fabe13ea7 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/DeleteToDo.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/DeleteToDo.dialog @@ -9,20 +9,20 @@ "actions": [ { "$kind": "Microsoft.SetProperty", - "value": "@title", + "value": "=@title", "property": "dialog.todo" }, { "$kind": "Microsoft.TextInput", "prompt": "OK, please enter the title of the todo you want to remove.", - "value": "@title", + "value": "=@title", "property": "dialog.todo" }, { "$kind": "Microsoft.EditArray", "changeType": "remove", "itemsProperty": "user.todos", - "value": "dialog.todo", + "value": "=dialog.todo", "resultProperty": "dialog.removed" }, { diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/ShowToDos.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/ShowToDos.dialog index a1aa094476..2193cb2323 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/ShowToDos.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/ShowToDos.dialog @@ -5,7 +5,6 @@ "triggers": [ { "$kind": "Microsoft.OnBeginDialog", - "actions": [ { "$kind": "Microsoft.IfCondition", diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/ToDoBot.main.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/ToDoBot.main.dialog index a267c7c32d..94491d7bc2 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/ToDoBot.main.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoBot/ToDoBot.main.dialog @@ -7,38 +7,26 @@ "$kind": "Microsoft.RegexRecognizer", "intents": [ { - - "intent": "AddIntent", - "pattern": "(?i)(?:add|create) .*(?:to-do|todo|task)(?: )?(?:named (?.*))?" + "pattern": "(?i)(?:add|create) .*(?:to-do|todo|task)(?: )?(?:named (?<title>.*))?" }, { - - "intent": "ClearIntent", - "pattern": "(?i)(?:delete|remove|clear) (?:all|every) (?:to-dos|todos|tasks)" + "pattern": "(?i)(?:delete|remove|clear) (?:all|every) (?:to-dos|todos|tasks)" }, { - - "intent": "DeleteIntent", - "pattern": "(?i)(?:delete|remove|clear) .*(?:to-do|todo|task)(?: )?(?:named (?<title>.*))?" + "pattern": "(?i)(?:delete|remove|clear) .*(?:to-do|todo|task)(?: )?(?:named (?<title>.*))?" }, { - - "intent": "ShowIntent", - "pattern": "(?i)(?:show|see|view) .*(?:to-do|todo|task)" + "pattern": "(?i)(?:show|see|view) .*(?:to-do|todo|task)" }, { - - "intent": "HelpIntent", - "pattern": "(?i)help" + "pattern": "(?i)help" }, { - - "intent": "CancelIntent", "pattern": "(?i)cancel|never mind" } diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.AddItem.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.AddItem.dialog index 519cdde2a4..785c1bb404 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.AddItem.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.AddItem.dialog @@ -8,12 +8,12 @@ "actions": [ { "$kind": "Microsoft.SetProperty", - "value": "@promptContentML", + "value": "=@promptContentML", "property": "dialog.item" }, { "$kind": "Microsoft.SetProperty", - "value": "@ListType", + "value": "=@ListType", "property": "dialog.listName" }, { diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.DeleteItem.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.DeleteItem.dialog index c2cb6ef61c..d80ccfb0f4 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.DeleteItem.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.DeleteItem.dialog @@ -8,12 +8,12 @@ "actions": [ { "$kind": "Microsoft.SetProperty", - "value": "@promptContentML", + "value": "=@promptContentML", "property": "dialog.item" }, { "$kind": "Microsoft.SetProperty", - "value": "@ListType", + "value": "=@ListType", "property": "dialog.listName" }, { diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.ShowItems.dialog b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.ShowItems.dialog index ef8babb2b3..9d91f216da 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.ShowItems.dialog +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/Samples/ToDoLuisBot/ToDoLuisBot.ShowItems.dialog @@ -8,7 +8,7 @@ "actions": [ { "$kind": "Microsoft.SetProperty", - "value": "@ListType", + "value": "=@ListType", "property": "dialog.listName" }, { diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/TestBot.cs b/tests/Microsoft.Bot.Builder.TestBot.Json/TestBot.cs index 2d9aee0ab0..137c9a4faf 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/TestBot.cs +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/TestBot.cs @@ -20,6 +20,7 @@ using Microsoft.Bot.Builder.Dialogs.Debugging; using Microsoft.Bot.Builder.Dialogs.Declarative; using Microsoft.Bot.Builder.Dialogs.Declarative.Resources; +using Newtonsoft.Json.Linq; namespace Microsoft.Bot.Builder.TestBot.Json { @@ -72,12 +73,14 @@ private void LoadDialogs() Cases = new List<Case>() }; + var choices = new ChoiceSet(); + foreach (var resource in this.resourceExplorer.GetResources(".dialog").Where(r => r.Id.EndsWith(".main.dialog"))) { try { var name = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(resource.Id)); - choiceInput.Choices.Value.Add(new Choice(name)); + choices.Add(new Choice(name)); var dialog = DeclarativeTypeLoader.Load<Dialog>(resource, this.resourceExplorer, DebugSupport.SourceMap); handleChoice.Cases.Add(new Case($"{name}", new List<Dialog>() { dialog })); } @@ -91,6 +94,7 @@ private void LoadDialogs() } } + choiceInput.Choices = new ChoiceSet(); choiceInput.Style = ListStyle.Auto; rootDialog.Triggers.Add(new OnBeginDialog() { diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/app.schema b/tests/Microsoft.Bot.Builder.TestBot.Json/app.schema index 2e80b11aaf..2b39f8263e 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/app.schema +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/app.schema @@ -10,6 +10,11 @@ "description": "", "$ref": "#/definitions/Microsoft.ActivityTemplate" }, + { + "title": "Microsoft.AdaptiveCardRecognizer", + "description": "Recognizer for detecting the value response from an Adaptive Card.", + "$ref": "#/definitions/Microsoft.AdaptiveCardRecognizer" + }, { "title": "Microsoft.AdaptiveDialog", "description": "Flexible, data driven dialog that can adapt to the conversation.", @@ -70,6 +75,11 @@ "description": "Stop executing this template and continue with the next iteration of the loop.", "$ref": "#/definitions/Microsoft.ContinueLoop" }, + { + "title": "Microsoft.CrossTrainedRecognizerSet", + "description": "Recognizer for selecting between cross trained recognizers.", + "$ref": "#/definitions/Microsoft.CrossTrainedRecognizerSet" + }, { "title": "Microsoft.CurrencyEntityRecognizer", "description": "Recognizer which recognizes currency.", @@ -90,6 +100,11 @@ "description": "If debugger is attached, stop the execution at this point in the conversation.", "$ref": "#/definitions/Microsoft.DebugBreak" }, + { + "title": "Microsoft.DeleteActivity", + "description": "Delete an activity that was previously sent.", + "$ref": "#/definitions/Microsoft.DeleteActivity" + }, { "title": "Microsoft.DeleteProperties", "description": "Delete multiple properties and any value it holds.", @@ -150,6 +165,16 @@ "description": "Execute actions on each page (collection of items) in an array.", "$ref": "#/definitions/Microsoft.ForeachPage" }, + { + "title": "Microsoft.GetActivityMembers", + "description": "Get the members who are participating in an activity. (BotFrameworkAdapter only)", + "$ref": "#/definitions/Microsoft.GetActivityMembers" + }, + { + "title": "Microsoft.GetConversationMembers", + "description": "Get the members who are participating in an conversation. (BotFrameworkAdapter only)", + "$ref": "#/definitions/Microsoft.GetConversationMembers" + }, { "title": "Microsoft.GotoAction", "description": "Go to an an action by id.", @@ -240,14 +265,9 @@ "description": "Actions to perform on receipt of a generic activity.", "$ref": "#/definitions/Microsoft.OnActivity" }, - { - "title": "Microsoft.OnEndOfActions", - "description": "This defines the actions to take when an OnEndOfActions event is raised", - "$ref": "#/definitions/Microsoft.OnEndOfActions" - }, { "title": "Microsoft.OnAssignEntity", - "description": "This defines the actions to take when an entity should be assigned to a property", + "description": "Actions to take when an entity should be assigned to a property.", "$ref": "#/definitions/Microsoft.OnAssignEntity" }, { @@ -262,17 +282,22 @@ }, { "title": "Microsoft.OnChooseEntity", - "description": "This defines the actions to take when a ChooseEntity event is raised", + "description": "Actions to be performed when an entity value needs to be resolved.", "$ref": "#/definitions/Microsoft.OnChooseEntity" }, + { + "title": "Microsoft.OnChooseIntent", + "description": "Actions to perform on when an intent is ambigious.", + "$ref": "#/definitions/Microsoft.OnChooseIntent" + }, { "title": "Microsoft.OnChooseProperty", - "description": "This defines the actions to take when a ChooseProperty event is raised", + "description": "Actions to take when there are multiple possible mappings of entities to properties.", "$ref": "#/definitions/Microsoft.OnChooseProperty" }, { "title": "Microsoft.OnClearProperty", - "description": "This defines the actions to take when a ClearProperty event is raised", + "description": "Actions to take when a property needs to be cleared.", "$ref": "#/definitions/Microsoft.OnClearProperty" }, { @@ -295,6 +320,11 @@ "description": "Actions to perform when a specific dialog event occurs.", "$ref": "#/definitions/Microsoft.OnDialogEvent" }, + { + "title": "Microsoft.OnEndOfActions", + "description": "Actions to take when there are no more actions in the current dialog.", + "$ref": "#/definitions/Microsoft.OnEndOfActions" + }, { "title": "Microsoft.OnEndOfConversationActivity", "description": "Actions to perform on receipt of an activity with type 'EndOfConversation'.", @@ -345,6 +375,11 @@ "description": "Actions to perform on receipt of an activity with type 'MessageUpdate'.", "$ref": "#/definitions/Microsoft.OnMessageUpdateActivity" }, + { + "title": "Microsoft.OnQnAMatch", + "description": "Actions to perform on when an match from QnAMaker is found.", + "$ref": "#/definitions/Microsoft.OnQnAMatch" + }, { "title": "Microsoft.OnRepromptDialog", "description": "Actions to perform when 'RepromptDialog' event occurs.", @@ -380,11 +415,21 @@ "description": "Dialog which uses QnAMAker knowledge base to answer questions.", "$ref": "#/definitions/Microsoft.QnAMakerDialog" }, + { + "title": "Microsoft.QnAMakerRecognizer", + "description": "Recognizer for generating QnAMatch intents from a KB.", + "$ref": "#/definitions/Microsoft.QnAMakerRecognizer" + }, { "title": "Microsoft.RandomSelector", "description": "Select most specific true rule", "$ref": "#/definitions/Microsoft.RandomSelector" }, + { + "title": "Microsoft.RecognizerSet", + "description": "Creates the union of the intents and entities of the recognizers in the set.", + "$ref": "#/definitions/Microsoft.RecognizerSet" + }, { "title": "Microsoft.RegExEntityRecognizer", "description": "Recognizer which recognizes patterns of input based on regex.", @@ -420,6 +465,11 @@ "description": "Set property to a value.", "$ref": "#/definitions/Microsoft.SetProperty" }, + { + "title": "Microsoft.SignOutUser", + "description": "Sign a user out that was logged in previously using OAuthInput.", + "$ref": "#/definitions/Microsoft.SignOutUser" + }, { "title": "Microsoft.StaticActivityTemplate", "description": "This allows you to define a static Activity object", @@ -505,6 +555,11 @@ "description": "Selector for all true events", "$ref": "#/definitions/Microsoft.TrueSelector" }, + { + "title": "Microsoft.UpdateActivity", + "description": "Respond with an activity.", + "$ref": "#/definitions/Microsoft.UpdateActivity" + }, { "title": "Microsoft.UrlEntityRecognizer", "description": "Recognizer which recognizes urls (example: http://bing.com)", @@ -579,6 +634,63 @@ } ] }, + "Microsoft.AdaptiveCardRecognizer": { + "$role": "union(Microsoft.Recognizer)", + "title": "Cross-trained Recognizer Set", + "description": "Recognizer for detecting the value response from an Adaptive Card.", + "type": "object", + "properties": { + "$kind": { + "title": "$kind", + "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", + "const": "Microsoft.AdaptiveCardRecognizer" + }, + "$copy": { + "title": "$copy", + "description": "Copy the definition by id from a .dialog file.", + "type": "string", + "pattern": "^(([a-zA-Z][a-zA-Z0-9.]*)?(#[a-zA-Z][a-zA-Z0-9.]*)?)$" + }, + "$id": { + "title": "$id", + "description": "Inline id for reuse of an inline definition", + "type": "string", + "pattern": "^([a-zA-Z][a-zA-Z0-9.]*)$" + }, + "$designer": { + "title": "$designer", + "type": "object", + "description": "Extra information for the Bot Framework Designer." + }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional unique id using with RecognizerSet." + } + }, + "additionalProperties": false, + "patternProperties": { + "^\\$": { + "type": "string" + } + }, + "anyOf": [ + { + "title": "Reference", + "required": [ + "$copy" + ] + }, + { + "title": "Type", + "required": [ + "$kind" + ] + } + ] + }, "Microsoft.AdaptiveDialog": { "$role": "union(Microsoft.IDialog)", "title": "Adaptive Dialog", @@ -627,10 +739,10 @@ "default": "dialog.result" }, "recognizer": { - "$kind": "Microsoft.IRecognizer", + "$kind": "Microsoft.Recognizer", "title": "Recognizer", - "description": "Language Understanding recognizer that interprets user input into intent and entities.", - "$ref": "#/definitions/Microsoft.IRecognizer" + "description": "Input recognizer that interprets user input into intent and entities.", + "$ref": "#/definitions/Microsoft.Recognizer" }, "generator": { "$kind": "Microsoft.ILanguageGenerator", @@ -776,6 +888,18 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "activity": { "$kind": "Microsoft.IActivityTemplate", "title": "Activity", @@ -783,12 +907,24 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "expectedProperties": { - "type": "array", + "$role": "expression", "title": "Expected Properties", "description": "Properties expected to be filled by entities from the user", - "items": { - "type": "string" - } + "oneOf": [ + { + "type": "array", + "items": { + "type": "string", + "title": "string" + }, + "title": "array" + }, + { + "type": "string", + "title": "string" + } + ], + "type": "string" } }, "additionalProperties": false, @@ -847,6 +983,18 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "prompt": { "$kind": "Microsoft.IActivityTemplate", "title": "Initial prompt", @@ -884,7 +1032,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -908,6 +1060,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -915,30 +1068,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -948,15 +1118,19 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { + "$role": "expression", "type": "string", "enum": [ "all", @@ -1023,8 +1197,22 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "dialog": { "$kind": "Microsoft.IDialog", + "$role": "expression", + "type": "string", "title": "Dialog name", "description": "Name of the dialog to call.", "examples": [ @@ -1033,7 +1221,11 @@ "$ref": "#/definitions/Microsoft.IDialog" }, "options": { - "type": "object", + "$role": "expression", + "type": [ + "string", + "object" + ], "title": "Options", "description": "One or more options that are passed to the dialog that is called.", "additionalProperties": { @@ -1041,20 +1233,24 @@ "title": "Options" } }, - "includeActivity": { - "type": "boolean", - "title": "Include Activity", - "description": "When set to true, dialog that is called can process the current activity.", - "default": false + "activityProcessed": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Activity Processed", + "description": "When set to false, the dialog that is called can process the current activity.", + "default": true }, "resultProperty": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store any value returned by the dialog that is called.", "examples": [ "dialog.userName" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -1112,6 +1308,18 @@ "type": "string", "title": "Id", "description": "Optional id for the dialog" + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] } }, "additionalProperties": false, @@ -1170,13 +1378,34 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "eventName": { + "$role": "expression", + "type": "string", "title": "Event name", - "description": "Name of the event to emit.", - "type": "string" + "description": "Name of the event to emit." }, "eventValue": { - "type": "object", + "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Event value", "description": "Value to emit with the event (optional).", "additionalProperties": true @@ -1238,6 +1467,18 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "prompt": { "$kind": "Microsoft.IActivityTemplate", "title": "Initial prompt", @@ -1275,7 +1516,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -1299,6 +1544,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -1306,30 +1552,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -1339,15 +1602,19 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { + "$role": "expression", "type": "string", "enum": [ "value", @@ -1600,6 +1867,18 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "prompt": { "$kind": "Microsoft.IActivityTemplate", "title": "Initial prompt", @@ -1637,7 +1916,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -1661,6 +1944,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -1668,30 +1952,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -1701,30 +2002,35 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the confirm output.", "examples": [ "concat('confirmation:', this.value)" - ], - "type": "string" + ] }, "defaultLocale": { + "$role": "expression", "type": "string", "title": "Default locale", "description": "Default locale.", "default": "en-us" }, "style": { + "$role": "expression", "type": "string", "enum": [ "None", @@ -1739,6 +2045,7 @@ "default": "Auto" }, "choiceOptions": { + "$role": "expression", "type": "object", "properties": { "inlineSeparator": { @@ -1765,9 +2072,11 @@ "description": "If true, inline and list style choices will be prefixed with the index of the choice.", "default": true } - } + }, + "description": "String must contain an expression." }, "confirmChoices": { + "$role": "expression", "type": "array", "items": [ { @@ -1793,7 +2102,8 @@ } } } - ] + ], + "description": "String must contain an expression." } }, "additionalProperties": false, @@ -1903,6 +2213,18 @@ "type": "string", "title": "Id", "description": "Optional id for the dialog" + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] } }, "additionalProperties": false, @@ -1926,10 +2248,10 @@ } ] }, - "Microsoft.CurrencyEntityRecognizer": { - "$role": "union(Microsoft.EntityRecognizers)", - "title": "Currency Entity Recognizer", - "description": "Recognizer which recognizes currency.", + "Microsoft.CrossTrainedRecognizerSet": { + "$role": "union(Microsoft.Recognizer)", + "title": "Cross-trained Recognizer Set", + "description": "Recognizer for selecting between cross trained recognizers.", "type": "object", "properties": { "$kind": { @@ -1937,7 +2259,7 @@ "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", "type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", - "const": "Microsoft.CurrencyEntityRecognizer" + "const": "Microsoft.CrossTrainedRecognizerSet" }, "$copy": { "title": "$copy", @@ -1955,7 +2277,74 @@ "title": "$designer", "type": "object", "description": "Extra information for the Bot Framework Designer." - } + }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional unique id using with RecognizerSet." + }, + "recognizers": { + "type": "array", + "title": "Recognizers", + "description": "List of Recognizers defined for this set.", + "items": { + "$kind": "Microsoft.Recognizer", + "$ref": "#/definitions/Microsoft.Recognizer" + } + } + }, + "additionalProperties": false, + "patternProperties": { + "^\\$": { + "type": "string" + } + }, + "anyOf": [ + { + "title": "Reference", + "required": [ + "$copy" + ] + }, + { + "title": "Type", + "required": [ + "recognizers", + "$kind" + ] + } + ] + }, + "Microsoft.CurrencyEntityRecognizer": { + "$role": "union(Microsoft.EntityRecognizers)", + "title": "Currency Entity Recognizer", + "description": "Recognizer which recognizes currency.", + "type": "object", + "properties": { + "$kind": { + "title": "$kind", + "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", + "const": "Microsoft.CurrencyEntityRecognizer" + }, + "$copy": { + "title": "$copy", + "description": "Copy the definition by id from a .dialog file.", + "type": "string", + "pattern": "^(([a-zA-Z][a-zA-Z0-9.]*)?(#[a-zA-Z][a-zA-Z0-9.]*)?)$" + }, + "$id": { + "title": "$id", + "description": "Inline id for reuse of an inline definition", + "type": "string", + "pattern": "^([a-zA-Z][a-zA-Z0-9.]*)$" + }, + "$designer": { + "title": "$designer", + "type": "object", + "description": "Extra information for the Bot Framework Designer." + } }, "additionalProperties": false, "patternProperties": { @@ -2065,6 +2454,18 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "prompt": { "$kind": "Microsoft.IActivityTemplate", "title": "Initial prompt", @@ -2102,7 +2503,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -2126,6 +2531,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -2133,30 +2539,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -2166,24 +2589,28 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the datetime output.", "examples": [ "this.value[0].Value" - ], - "type": "string" + ] }, "defaultLocale": { + "$role": "expression", "type": "string", "title": "Default locale", "description": "Default locale.", @@ -2245,6 +2672,96 @@ "type": "string", "title": "Id", "description": "Optional id for the dialog" + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + } + }, + "additionalProperties": false, + "patternProperties": { + "^\\$": { + "type": "string" + } + }, + "anyOf": [ + { + "title": "Reference", + "required": [ + "$copy" + ] + }, + { + "title": "Type", + "required": [ + "$kind" + ] + } + ] + }, + "Microsoft.DeleteActivity": { + "$role": "union(Microsoft.IDialog)", + "title": "Delete Activity", + "description": "Delete an activity that was previously sent.", + "type": "object", + "properties": { + "$kind": { + "title": "$kind", + "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", + "const": "Microsoft.DeleteActivity" + }, + "$copy": { + "title": "$copy", + "description": "Copy the definition by id from a .dialog file.", + "type": "string", + "pattern": "^(([a-zA-Z][a-zA-Z0-9.]*)?(#[a-zA-Z][a-zA-Z0-9.]*)?)$" + }, + "$id": { + "title": "$id", + "description": "Inline id for reuse of an inline definition", + "type": "string", + "pattern": "^([a-zA-Z][a-zA-Z0-9.]*)$" + }, + "$designer": { + "title": "$designer", + "type": "object", + "description": "Extra information for the Bot Framework Designer." + }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional id for the dialog" + }, + "activityId": { + "$role": "expression", + "type": "string", + "title": "ActivityId", + "description": "expression to an activityId to delete", + "examples": [ + "=$lastActivity" + ] + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] } }, "additionalProperties": false, @@ -2263,6 +2780,8 @@ { "title": "Type", "required": [ + "property", + "value", "$kind" ] } @@ -2303,15 +2822,27 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "properties": { "type": "array", "title": "Properties", "description": "Properties to delete.", "items": { "$role": "expression", + "type": "string", "title": "Property", - "description": "Property to delete.", - "type": "string" + "description": "Property to delete." } } }, @@ -2372,11 +2903,23 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "property": { "$role": "expression", + "type": "string", "title": "Property", - "description": "Property to delete.", - "type": "string" + "description": "Property to delete." } }, "additionalProperties": false, @@ -2488,16 +3031,29 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "changeType": { + "$role": "expression", "type": "string", "title": "Type of change", "description": "Type of change to apply to the current actions.", "enum": [ - "InsertActions", - "InsertActionsBeforeTags", - "AppendActions", - "EndSequence", - "ReplaceSequence" + "insertActions", + "insertActionsBeforeTags", + "appendActions", + "endSequence", + "replaceSequence" ] }, "actions": { @@ -2569,39 +3125,59 @@ "description": "Optional id for the dialog" }, "changeType": { + "$role": "expression", "type": "string", "title": "Type of change", "description": "Type of change to the array in memory.", "enum": [ - "Push", - "Pop", - "Take", - "Remove", - "Clear" + "push", + "pop", + "take", + "remove", + "clear" + ] + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" ] }, "itemsProperty": { "$role": "expression", + "type": "string", "title": "Items property", - "description": "Property that holds the array to update.", - "type": "string" + "description": "Property that holds the array to update." }, "resultProperty": { "$role": "expression", + "type": "string", "title": "Result Property", - "description": "Property to store the result of this action.", - "type": "string" + "description": "Property to store the result of this action." }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "New value or expression.", "examples": [ "'milk'", "dialog.favColor", "dialog.favColor == 'red'" - ], - "type": "string" + ] } }, "additionalProperties": false, @@ -2714,41 +3290,60 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "eventName": { + "$role": "expression", + "type": "string", "title": "Event name", "description": "Name of the event to emit.", - "anyOf": [ - { - "enum": [ - "beginDialog", - "resumeDialog", - "repromptDialog", - "cancelDialog", - "endDialog", - "activityReceived", - "recognizedIntent", - "unknownIntent", - "actionsStarted", - "actionsSaved", - "actionsEnded", - "actionsResumed" - ] - }, - { - "type": "string" - } + "enum": [ + "beginDialog", + "resumeDialog", + "repromptDialog", + "cancelDialog", + "endDialog", + "activityReceived", + "recognizedIntent", + "unknownIntent", + "actionsStarted", + "actionsSaved", + "actionsEnded", + "actionsResumed" ] }, "eventValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Event value", - "description": "Value to emit with the event (optional).", - "type": "string" + "description": "Value to emit with the event (optional)." }, "bubbleEvent": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Bubble event", - "description": "If true this event is passed on to parent dialogs." + "description": "If true this event is passed on to parent dialogs.", + "default": false } }, "additionalProperties": false, @@ -2808,15 +3403,34 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Result value returned to the parent dialog.", "examples": [ - "dialog.userName", - "'tomato'" - ], - "type": "string" + "=dialog.userName", + "='tomato'" + ] } }, "additionalProperties": false, @@ -2874,6 +3488,18 @@ "type": "string", "title": "Id", "description": "Optional id for the dialog" + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] } }, "additionalProperties": false, @@ -3082,14 +3708,28 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "itemsProperty": { "$role": "expression", + "type": [ + "string" + ], "title": "Items property", "description": "Property that holds the array.", "examples": [ "user.todoList" - ], - "type": "string" + ] }, "actions": { "type": "array", @@ -3159,14 +3799,26 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "itemsProperty": { "$role": "expression", + "type": "string", "title": "Items property", "description": "Property that holds the array.", "examples": [ "user.todoList" - ], - "type": "string" + ] }, "actions": { "type": "array", @@ -3178,7 +3830,11 @@ } }, "pageSize": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Page size", "description": "Number of items in each page.", "default": 10 @@ -3207,6 +3863,153 @@ } ] }, + "Microsoft.GetActivityMembers": { + "$role": "union(Microsoft.IDialog)", + "title": "Get Activity Members", + "description": "Get the members who are participating in an activity. (BotFrameworkAdapter only)", + "type": "object", + "properties": { + "$kind": { + "title": "$kind", + "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", + "const": "Microsoft.GetActivityMembers" + }, + "$copy": { + "title": "$copy", + "description": "Copy the definition by id from a .dialog file.", + "type": "string", + "pattern": "^(([a-zA-Z][a-zA-Z0-9.]*)?(#[a-zA-Z][a-zA-Z0-9.]*)?)$" + }, + "$id": { + "title": "$id", + "description": "Inline id for reuse of an inline definition", + "type": "string", + "pattern": "^([a-zA-Z][a-zA-Z0-9.]*)$" + }, + "$designer": { + "title": "$designer", + "type": "object", + "description": "Extra information for the Bot Framework Designer." + }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional id for the dialog" + }, + "activityId": { + "$role": "expression", + "type": "string", + "title": "ActivityId", + "description": "expression to an activityId to get the members. If none is defined then the current activity id will be used.", + "examples": [ + "$lastActivity" + ] + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + } + }, + "additionalProperties": false, + "patternProperties": { + "^\\$": { + "type": "string" + } + }, + "anyOf": [ + { + "title": "Reference", + "required": [ + "$copy" + ] + }, + { + "title": "Type", + "required": [ + "$kind" + ] + } + ] + }, + "Microsoft.GetConversationMembers": { + "$role": "union(Microsoft.IDialog)", + "title": "Get Converation Members", + "description": "Get the members who are participating in an conversation. (BotFrameworkAdapter only)", + "type": "object", + "properties": { + "$kind": { + "title": "$kind", + "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", + "const": "Microsoft.GetConversationMembers" + }, + "$copy": { + "title": "$copy", + "description": "Copy the definition by id from a .dialog file.", + "type": "string", + "pattern": "^(([a-zA-Z][a-zA-Z0-9.]*)?(#[a-zA-Z][a-zA-Z0-9.]*)?)$" + }, + "$id": { + "title": "$id", + "description": "Inline id for reuse of an inline definition", + "type": "string", + "pattern": "^([a-zA-Z][a-zA-Z0-9.]*)$" + }, + "$designer": { + "title": "$designer", + "type": "object", + "description": "Extra information for the Bot Framework Designer." + }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional id for the dialog" + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + } + }, + "additionalProperties": false, + "patternProperties": { + "^\\$": { + "type": "string" + } + }, + "anyOf": [ + { + "title": "Reference", + "required": [ + "$copy" + ] + }, + { + "title": "Type", + "required": [ + "$kind" + ] + } + ] + }, "Microsoft.GotoAction": { "$role": "union(Microsoft.IDialog)", "title": "Go to Action", @@ -3242,7 +4045,20 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "actionId": { + "$role": "expression", "type": "string", "title": "Action Id", "description": "Action Id to execute next" @@ -3409,6 +4225,18 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "method": { "type": "string", "title": "HTTP method", @@ -3426,6 +4254,7 @@ ] }, "url": { + "$role": "expression", "type": "string", "title": "Url", "description": "URL to call (supports data binding).", @@ -3434,27 +4263,40 @@ ] }, "body": { - "type": "object", + "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Body", "description": "Body to include in the HTTP call (supports data binding).", "additionalProperties": true }, "resultProperty": { "$role": "expression", + "type": "string", "title": "Result property", "description": "Property to store the result of this action. The result includes 4 properties from the http response: statusCode, reasonPhrase, content and headers. If the content is json it will be a deserialized object.", "examples": [ "dialog.contosodata" - ], - "type": "string" + ] }, "headers": { "type": "object", - "additionalProperties": true, "title": "Headers", - "description": "One or more headers to include in the request (supports data binding)." + "description": "One or more headers to include in the request (supports data binding).", + "additionalProperties": { + "$role": "expression", + "type": "string", + "description": "String must contain an expression." + } }, "responseType": { + "$role": "expression", "type": "string", "title": "Response type", "description": "Defines the type of HTTP response. Automatically calls the 'Send a response' action if set to 'Activity' or 'Activities'.", @@ -3571,6 +4413,11 @@ "description": "If debugger is attached, stop the execution at this point in the conversation.", "$ref": "#/definitions/Microsoft.DebugBreak" }, + { + "title": "Microsoft.DeleteActivity", + "description": "Delete an activity that was previously sent.", + "$ref": "#/definitions/Microsoft.DeleteActivity" + }, { "title": "Microsoft.DeleteProperties", "description": "Delete multiple properties and any value it holds.", @@ -3616,6 +4463,16 @@ "description": "Execute actions on each page (collection of items) in an array.", "$ref": "#/definitions/Microsoft.ForeachPage" }, + { + "title": "Microsoft.GetActivityMembers", + "description": "Get the members who are participating in an activity. (BotFrameworkAdapter only)", + "$ref": "#/definitions/Microsoft.GetActivityMembers" + }, + { + "title": "Microsoft.GetConversationMembers", + "description": "Get the members who are participating in an conversation. (BotFrameworkAdapter only)", + "$ref": "#/definitions/Microsoft.GetConversationMembers" + }, { "title": "Microsoft.GotoAction", "description": "Go to an an action by id.", @@ -3681,6 +4538,11 @@ "description": "Set property to a value.", "$ref": "#/definitions/Microsoft.SetProperty" }, + { + "title": "Microsoft.SignOutUser", + "description": "Sign a user out that was logged in previously using OAuthInput.", + "$ref": "#/definitions/Microsoft.SignOutUser" + }, { "title": "Microsoft.SwitchCondition", "description": "Execute different actions based on the value of a property.", @@ -3701,6 +4563,11 @@ "description": "Send a trace activity to the transcript logger and/ or Bot Framework Emulator.", "$ref": "#/definitions/Microsoft.TraceActivity" }, + { + "title": "Microsoft.UpdateActivity", + "description": "Respond with an activity.", + "$ref": "#/definitions/Microsoft.UpdateActivity" + }, { "type": "string", "title": "string" @@ -3728,32 +4595,6 @@ } ] }, - "Microsoft.IRecognizer": { - "title": "Microsoft IRecognizer", - "description": "Union of components which implement the IRecognizer interface", - "$role": "union", - "oneOf": [ - { - "title": "Microsoft.LuisRecognizer", - "description": "LUIS recognizer.", - "$ref": "#/definitions/Microsoft.LuisRecognizer" - }, - { - "title": "Microsoft.MultiLanguageRecognizer", - "description": "Configure one recognizer per language and the specify the language fallback policy.", - "$ref": "#/definitions/Microsoft.MultiLanguageRecognizer" - }, - { - "title": "Microsoft.RegexRecognizer", - "description": "Use regular expressions to recognize intents and entities from user input.", - "$ref": "#/definitions/Microsoft.RegexRecognizer" - }, - { - "type": "string", - "title": "string" - } - ] - }, "Microsoft.ITextTemplate": { "title": "Microsoft TextTemplate", "description": "Union of components which implement the TextTemplate", @@ -3780,14 +4621,9 @@ "description": "Actions to perform on receipt of a generic activity.", "$ref": "#/definitions/Microsoft.OnActivity" }, - { - "title": "Microsoft.OnEndOfActions", - "description": "This defines the actions to take when an OnEndOfActions event is raised", - "$ref": "#/definitions/Microsoft.OnEndOfActions" - }, { "title": "Microsoft.OnAssignEntity", - "description": "This defines the actions to take when an entity should be assigned to a property", + "description": "Actions to take when an entity should be assigned to a property.", "$ref": "#/definitions/Microsoft.OnAssignEntity" }, { @@ -3802,17 +4638,22 @@ }, { "title": "Microsoft.OnChooseEntity", - "description": "This defines the actions to take when a ChooseEntity event is raised", + "description": "Actions to be performed when an entity value needs to be resolved.", "$ref": "#/definitions/Microsoft.OnChooseEntity" }, + { + "title": "Microsoft.OnChooseIntent", + "description": "Actions to perform on when an intent is ambigious.", + "$ref": "#/definitions/Microsoft.OnChooseIntent" + }, { "title": "Microsoft.OnChooseProperty", - "description": "This defines the actions to take when a ChooseProperty event is raised", + "description": "Actions to take when there are multiple possible mappings of entities to properties.", "$ref": "#/definitions/Microsoft.OnChooseProperty" }, { "title": "Microsoft.OnClearProperty", - "description": "This defines the actions to take when a ClearProperty event is raised", + "description": "Actions to take when a property needs to be cleared.", "$ref": "#/definitions/Microsoft.OnClearProperty" }, { @@ -3835,6 +4676,11 @@ "description": "Actions to perform when a specific dialog event occurs.", "$ref": "#/definitions/Microsoft.OnDialogEvent" }, + { + "title": "Microsoft.OnEndOfActions", + "description": "Actions to take when there are no more actions in the current dialog.", + "$ref": "#/definitions/Microsoft.OnEndOfActions" + }, { "title": "Microsoft.OnEndOfConversationActivity", "description": "Actions to perform on receipt of an activity with type 'EndOfConversation'.", @@ -3885,6 +4731,11 @@ "description": "Actions to perform on receipt of an activity with type 'MessageUpdate'.", "$ref": "#/definitions/Microsoft.OnMessageUpdateActivity" }, + { + "title": "Microsoft.OnQnAMatch", + "description": "Actions to perform on when an match from QnAMaker is found.", + "$ref": "#/definitions/Microsoft.OnQnAMatch" + }, { "title": "Microsoft.OnRepromptDialog", "description": "Actions to perform when 'RepromptDialog' event occurs.", @@ -3971,12 +4822,27 @@ }, "condition": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Condition", "description": "Expression to evaluate.", "examples": [ "user.age > 3" + ] + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" ], - "type": "string" + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] }, "actions": { "type": "array", @@ -4055,16 +4921,29 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property (named location to store information).", "examples": [ "user.age" - ], - "type": "string" + ] }, "type": { + "$role": "expression", "type": "string", "title": "Type", "description": "Type of value.", @@ -4235,13 +5114,36 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "text": { + "$role": "expression", "type": "string", "title": "Text", "description": "Information to log." }, + "label": { + "$role": "expression", + "type": "string", + "title": "Label", + "description": "Label for the trace activity (used to identify it in a list of trace activities.)" + }, "traceActivity": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Send Trace Activity", "description": "If true, automatically sends a TraceActivity (view in Bot Framework Emulator).", "default": false @@ -4270,7 +5172,7 @@ ] }, "Microsoft.LuisRecognizer": { - "$role": "union(Microsoft.IRecognizer)", + "$role": "union(Microsoft.Recognizer)", "title": "LUIS Recognizer", "description": "LUIS recognizer.", "type": "object", @@ -4300,6 +5202,11 @@ "type": "object", "description": "Extra information for the Bot Framework Designer." }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional unique id using with RecognizerSet. Other recognizers should return 'DeferToRecognizer_{Id}' intent when cross training data for this recognizer." + }, "applicationId": { "type": "string", "title": "LUIS Application ID", @@ -4486,7 +5393,7 @@ ] }, "Microsoft.MultiLanguageRecognizer": { - "$role": "union(Microsoft.IRecognizer)", + "$role": "union(Microsoft.Recognizer)", "title": "Multi-language recognizer", "description": "Configure one recognizer per language and the specify the language fallback policy.", "type": "object", @@ -4515,6 +5422,11 @@ "type": "object", "description": "Extra information for the Bot Framework Designer." }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional unique id using with RecognizerSet. Other recognizers should return 'DeferToRecognizer_{Id}' intent when cross training data for this recognizer." + }, "languagePolicy": { "$kind": "Microsoft.LanguagePolicy", "type": "object", @@ -4525,10 +5437,10 @@ "recognizers": { "type": "object", "title": "Recognizers", - "description": "Map of language -> IRecognizer", + "description": "Map of language -> Recognizer", "additionalProperties": { - "$kind": "Microsoft.IRecognizer", - "$ref": "#/definitions/Microsoft.IRecognizer" + "$kind": "Microsoft.Recognizer", + "$ref": "#/definitions/Microsoft.Recognizer" } } }, @@ -4641,10 +5553,22 @@ "title": "Id", "description": "Optional id for the dialog" }, - "prompt": { - "$kind": "Microsoft.IActivityTemplate", - "title": "Initial prompt", - "description": "Message to send to collect information.", + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, + "prompt": { + "$kind": "Microsoft.IActivityTemplate", + "title": "Initial prompt", + "description": "Message to send to collect information.", "examples": [ "What is your birth date?" ], @@ -4678,7 +5602,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -4702,6 +5630,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -4709,30 +5638,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -4742,24 +5688,28 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the number output.", "examples": [ - "int(this.value)" - ], - "type": "string" + "@{int(this.value)}" + ] }, "defaultLocale": { + "$role": "expression", "type": "string", "title": "Default locale", "description": "Default locale.", @@ -4870,6 +5820,7 @@ "description": "Extra information for the Bot Framework Designer." }, "connectionName": { + "$role": "expression", "type": "string", "title": "Connection name", "description": "The connection name configured in Azure Web App Bot OAuth settings.", @@ -4877,7 +5828,20 @@ "msgraphOAuthConnection" ] }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "text": { + "$role": "expression", "type": "string", "title": "Text", "description": "Text shown in the OAuth signin card.", @@ -4886,6 +5850,7 @@ ] }, "title": { + "$role": "expression", "type": "string", "title": "Title", "description": "Title shown in the OAuth signin card.", @@ -4894,19 +5859,83 @@ ] }, "timeout": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Timeout", "description": "Time out setting for the OAuth signin card.", "default": "900000" }, - "tokenProperty": { + "property": { "$role": "expression", + "type": "string", "title": "Token property", "description": "Property to store the OAuth token result.", "examples": [ "dialog.token" + ] + }, + "invalidPrompt": { + "$kind": "Microsoft.IActivityTemplate", + "title": "Invalid prompt", + "description": "Message to send if user response is invalid.", + "examples": [ + "Sorry, the login info you provided is not valid." ], - "type": "string" + "$ref": "#/definitions/Microsoft.IActivityTemplate" + }, + "defaultValueResponse": { + "$kind": "Microsoft.IActivityTemplate", + "title": "Default value response", + "description": "Message to send when max turn count (if specified) has been exceeded and the default value is selected as the value.", + "examples": [ + "Login failed." + ], + "$ref": "#/definitions/Microsoft.IActivityTemplate" + }, + "maxTurnCount": { + "$role": "expression", + "type": [ + "integer", + "string" + ], + "title": "Max turn count", + "description": "Maximum number of re-prompt attempts to collect information.", + "default": 3, + "examples": [ + 3 + ] + }, + "defaultValue": { + "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], + "title": "Default value", + "description": "Expression to examine on each turn of the conversation as possible value to the property.", + "examples": [ + "@token" + ] + }, + "allowInterruptions": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Allow Interruptions", + "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", + "default": "true", + "examples": [ + "true" + ] } }, "additionalProperties": false, @@ -5018,10 +6047,10 @@ } ] }, - "Microsoft.OnEndOfActions": { + "Microsoft.OnAssignEntity": { "$role": "union(Microsoft.ITriggerCondition)", - "title": "Ask Event", - "description": "This defines the actions to take when an OnEndOfActions event is raised", + "title": "On entity assignment", + "description": "Actions to take when an entity should be assigned to a property.", "type": "object", "properties": { "$kind": { @@ -5029,7 +6058,7 @@ "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", "type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", - "const": "Microsoft.OnEndOfActions" + "const": "Microsoft.OnAssignEntity" }, "$copy": { "title": "$copy", @@ -5075,6 +6104,20 @@ "type": "boolean", "title": "Run Once", "description": "True if rule should run once per unique conditions" + }, + "property": { + "type": "string", + "title": "Property", + "description": "Property that will be set after entity is selected." + }, + "entity": { + "type": "string", + "title": "Entity", + "description": "Entity being put into property" + }, + "operation": { + "type": "string", + "title": "Operation to use for assigning entity" } }, "additionalProperties": false, @@ -5099,10 +6142,10 @@ } ] }, - "Microsoft.OnAssignEntity": { + "Microsoft.OnBeginDialog": { "$role": "union(Microsoft.ITriggerCondition)", - "title": "Assign an entity to a property", - "description": "This defines the actions to take when an entity should be assigned to a property", + "title": "On begin dialog", + "description": "Actions to perform when this dialog begins.", "type": "object", "properties": { "$kind": { @@ -5110,7 +6153,7 @@ "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", "type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", - "const": "Microsoft.OnAssignEntity" + "const": "Microsoft.OnBeginDialog" }, "$copy": { "title": "$copy", @@ -5156,20 +6199,6 @@ "type": "boolean", "title": "Run Once", "description": "True if rule should run once per unique conditions" - }, - "property": { - "type": "string", - "title": "Property", - "description": "Property that will be set after entity is selected." - }, - "entity": { - "type": "string", - "title": "Entity", - "description": "Entity being put into property" - }, - "operation": { - "type": "string", - "title": "Operation to use for assigning entity" } }, "additionalProperties": false, @@ -5194,10 +6223,10 @@ } ] }, - "Microsoft.OnBeginDialog": { + "Microsoft.OnCancelDialog": { "$role": "union(Microsoft.ITriggerCondition)", - "title": "On begin dialog", - "description": "Actions to perform when this dialog begins.", + "title": "On cancel dialog", + "description": "Actions to perform on cancel dialog event.", "type": "object", "properties": { "$kind": { @@ -5205,7 +6234,7 @@ "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", "type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", - "const": "Microsoft.OnBeginDialog" + "const": "Microsoft.OnCancelDialog" }, "$copy": { "title": "$copy", @@ -5275,10 +6304,10 @@ } ] }, - "Microsoft.OnCancelDialog": { + "Microsoft.OnChooseEntity": { "$role": "union(Microsoft.ITriggerCondition)", - "title": "On cancel dialog", - "description": "Actions to perform on cancel dialog event.", + "title": "On choose entity", + "description": "Actions to be performed when an entity value needs to be resolved.", "type": "object", "properties": { "$kind": { @@ -5286,7 +6315,7 @@ "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", "type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", - "const": "Microsoft.OnCancelDialog" + "const": "Microsoft.OnChooseEntity" }, "$copy": { "title": "$copy", @@ -5332,6 +6361,16 @@ "type": "boolean", "title": "Run Once", "description": "True if rule should run once per unique conditions" + }, + "property": { + "type": "string", + "title": "Property to be set", + "description": "Property that will be set after entity is selected." + }, + "entity": { + "type": "string", + "title": "Ambiguous entity", + "description": "Ambiguous entity" } }, "additionalProperties": false, @@ -5356,10 +6395,10 @@ } ] }, - "Microsoft.OnChooseEntity": { + "Microsoft.OnChooseIntent": { "$role": "union(Microsoft.ITriggerCondition)", - "title": "ChooseEntity Event", - "description": "This defines the actions to take when a ChooseEntity event is raised", + "title": "On ambigious intent", + "description": "Actions to perform on when an intent is ambigious.", "type": "object", "properties": { "$kind": { @@ -5367,7 +6406,7 @@ "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", "type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", - "const": "Microsoft.OnChooseEntity" + "const": "Microsoft.OnChooseIntent" }, "$copy": { "title": "$copy", @@ -5414,15 +6453,13 @@ "title": "Run Once", "description": "True if rule should run once per unique conditions" }, - "property": { - "type": "string", - "title": "Property to be set", - "description": "Property that will be set after entity is selected." - }, - "entity": { - "type": "string", - "title": "Ambiguous entity", - "description": "Ambiguous entity" + "intents": { + "type": "array", + "title": "Intents", + "description": "Intents that must be in the ChooseIntent result for this condition to trigger.", + "items": { + "type": "string" + } } }, "additionalProperties": false, @@ -5449,8 +6486,8 @@ }, "Microsoft.OnChooseProperty": { "$role": "union(Microsoft.ITriggerCondition)", - "title": "ChooseProperty Event", - "description": "This defines the actions to take when a ChooseProperty event is raised", + "title": "On choose property", + "description": "Actions to take when there are multiple possible mappings of entities to properties.", "type": "object", "properties": { "$kind": { @@ -5553,8 +6590,8 @@ }, "Microsoft.OnClearProperty": { "$role": "union(Microsoft.ITriggerCondition)", - "title": "ClearProperty Event", - "description": "This defines the actions to take when a ClearProperty event is raised", + "title": "On clear property", + "description": "Actions to take when a property needs to be cleared.", "type": "object", "properties": { "$kind": { @@ -5973,6 +7010,87 @@ } ] }, + "Microsoft.OnEndOfActions": { + "$role": "union(Microsoft.ITriggerCondition)", + "title": "On end of actions", + "description": "Actions to take when there are no more actions in the current dialog.", + "type": "object", + "properties": { + "$kind": { + "title": "$kind", + "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", + "const": "Microsoft.OnEndOfActions" + }, + "$copy": { + "title": "$copy", + "description": "Copy the definition by id from a .dialog file.", + "type": "string", + "pattern": "^(([a-zA-Z][a-zA-Z0-9.]*)?(#[a-zA-Z][a-zA-Z0-9.]*)?)$" + }, + "$id": { + "title": "$id", + "description": "Inline id for reuse of an inline definition", + "type": "string", + "pattern": "^([a-zA-Z][a-zA-Z0-9.]*)$" + }, + "$designer": { + "title": "$designer", + "type": "object", + "description": "Extra information for the Bot Framework Designer." + }, + "condition": { + "$role": "expression", + "title": "Condition", + "description": "Condition (expression).", + "examples": [ + "user.vip == true" + ], + "type": "string" + }, + "actions": { + "type": "array", + "description": "Sequence of actions to execute.", + "items": { + "$kind": "Microsoft.IDialog", + "$ref": "#/definitions/Microsoft.IDialog" + } + }, + "priority": { + "type": "string", + "title": "priority", + "description": "Priority expression of rule with 0 being the most important", + "$role": "expression" + }, + "runOnce": { + "type": "boolean", + "title": "Run Once", + "description": "True if rule should run once per unique conditions" + } + }, + "additionalProperties": false, + "patternProperties": { + "^\\$": { + "type": "string" + } + }, + "anyOf": [ + { + "title": "Reference", + "required": [ + "$copy" + ] + }, + { + "title": "Type", + "required": [ + "actions", + "$kind" + ] + } + ] + }, "Microsoft.OnEndOfConversationActivity": { "$role": "union(Microsoft.ITriggerCondition)", "title": "On EndOfConversation activity", @@ -6386,7 +7504,6 @@ "title": "Type", "required": [ "actions", - "intent", "$kind" ] } @@ -6797,10 +7914,91 @@ } ] }, - "Microsoft.OnRepromptDialog": { + "Microsoft.OnQnAMatch": { "$role": "union(Microsoft.ITriggerCondition)", - "title": "On RepromptDialog", - "description": "Actions to perform when 'RepromptDialog' event occurs.", + "title": "On QnAMaker Match", + "description": "Actions to perform on when an match from QnAMaker is found.", + "type": "object", + "properties": { + "$kind": { + "title": "$kind", + "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", + "const": "Microsoft.OnQnAMatch" + }, + "$copy": { + "title": "$copy", + "description": "Copy the definition by id from a .dialog file.", + "type": "string", + "pattern": "^(([a-zA-Z][a-zA-Z0-9.]*)?(#[a-zA-Z][a-zA-Z0-9.]*)?)$" + }, + "$id": { + "title": "$id", + "description": "Inline id for reuse of an inline definition", + "type": "string", + "pattern": "^([a-zA-Z][a-zA-Z0-9.]*)$" + }, + "$designer": { + "title": "$designer", + "type": "object", + "description": "Extra information for the Bot Framework Designer." + }, + "condition": { + "$role": "expression", + "title": "Condition", + "description": "Condition (expression).", + "examples": [ + "user.vip == true" + ], + "type": "string" + }, + "actions": { + "type": "array", + "description": "Sequence of actions to execute.", + "items": { + "$kind": "Microsoft.IDialog", + "$ref": "#/definitions/Microsoft.IDialog" + } + }, + "priority": { + "type": "string", + "title": "priority", + "description": "Priority expression of rule with 0 being the most important", + "$role": "expression" + }, + "runOnce": { + "type": "boolean", + "title": "Run Once", + "description": "True if rule should run once per unique conditions" + } + }, + "additionalProperties": false, + "patternProperties": { + "^\\$": { + "type": "string" + } + }, + "anyOf": [ + { + "title": "Reference", + "required": [ + "$copy" + ] + }, + { + "title": "Type", + "required": [ + "actions", + "$kind" + ] + } + ] + }, + "Microsoft.OnRepromptDialog": { + "$role": "union(Microsoft.ITriggerCondition)", + "title": "On RepromptDialog", + "description": "Actions to perform when 'RepromptDialog' event occurs.", "type": "object", "properties": { "$kind": { @@ -7229,27 +8427,27 @@ }, "knowledgeBaseId": { "$role": "expression", + "type": "string", "title": "KnowledgeBase Id", "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", - "default": "settings.qna.knowledgebaseid", - "type": "string" + "default": "=settings.qna.knowledgebaseid" }, "endpointKey": { "$role": "expression", + "type": "string", "title": "Endpoint Key", "description": "Endpoint key for the QnA Maker KB.", - "default": "settings.qna.endpointkey", - "type": "string" + "default": "=settings.qna.endpointkey" }, "hostname": { "$role": "expression", + "type": "string", "title": "Hostname", "description": "Hostname for your QnA Maker service.", - "default": "settings.qna.hostname", + "default": "=settings.qna.hostname", "examples": [ "https://yourserver.azurewebsites.net/qnamaker" - ], - "type": "string" + ] }, "noAnswer": { "$kind": "Microsoft.IActivityTemplate", @@ -7259,18 +8457,24 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "threshold": { - "type": "number", + "$role": "expression", + "type": [ + "number", + "string" + ], "title": "Threshold", "description": "Threshold score to filter results.", "default": 0.3 }, "activeLearningCardTitle": { + "$role": "expression", "type": "string", "title": "Active learning card title", "description": "Title for active learning suggestions card.", "default": "Did you mean:" }, "cardNoMatchText": { + "$role": "expression", "type": "string", "title": "Card no match text", "description": "Text for no match option.", @@ -7283,6 +8487,146 @@ "default": "Thanks for the feedback.", "$ref": "#/definitions/Microsoft.IActivityTemplate" }, + "strictFilters": { + "$role": "expression", + "type": [ + "array", + "string" + ], + "title": "Strict Filters", + "description": "Metadata filters to use when calling the QnA Maker KB.", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name", + "maximum": 100 + }, + "value": { + "type": "string", + "title": "Value", + "maximum": 100 + } + } + } + }, + "top": { + "$role": "expression", + "type": [ + "number", + "string" + ], + "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": { + "type": "string", + "title": "RankerType", + "description": "Type of Ranker.", + "enum": [ + "Default", + "QuestionOnly", + "AutoSuggestQuestion" + ], + "default": "Default" + } + }, + "patternProperties": { + "^\\$": { + "type": "string" + } + }, + "anyOf": [ + { + "title": "Reference", + "required": [ + "$copy" + ] + }, + { + "title": "Type", + "required": [ + "knowledgeBaseId", + "endpointKey", + "hostname", + "$kind" + ] + } + ] + }, + "Microsoft.QnAMakerRecognizer": { + "$role": "union(Microsoft.Recognizer)", + "title": "QnAMaker Recognizer", + "description": "Recognizer for generating QnAMatch intents from a KB.", + "type": "object", + "properties": { + "$kind": { + "title": "$kind", + "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", + "const": "Microsoft.QnAMakerRecognizer" + }, + "$copy": { + "title": "$copy", + "description": "Copy the definition by id from a .dialog file.", + "type": "string", + "pattern": "^(([a-zA-Z][a-zA-Z0-9.]*)?(#[a-zA-Z][a-zA-Z0-9.]*)?)$" + }, + "$id": { + "title": "$id", + "description": "Inline id for reuse of an inline definition", + "type": "string", + "pattern": "^([a-zA-Z][a-zA-Z0-9.]*)$" + }, + "$designer": { + "title": "$designer", + "type": "object", + "description": "Extra information for the Bot Framework Designer." + }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional unique id using with RecognizerSet." + }, + "knowledgeBaseId": { + "$role": "expression", + "title": "KnowledgeBase Id", + "description": "KnowledgeBase Id of your QnA Maker KnowledgeBase.", + "default": "settings.qna.knowledgebaseid", + "type": "string" + }, + "endpointKey": { + "$role": "expression", + "title": "Endpoint Key", + "description": "Endpoint key for the QnA Maker KB.", + "default": "settings.qna.endpointkey", + "type": "string" + }, + "hostname": { + "$role": "expression", + "title": "Hostname", + "description": "Hostname for your QnA Maker service.", + "default": "settings.qna.hostname", + "examples": [ + "https://yourserver.azurewebsites.net/qnamaker" + ], + "type": "string" + }, + "threshold": { + "type": "number", + "title": "Threshold", + "description": "Threshold score to filter results.", + "default": 0.3 + }, "strictFilters": { "type": "array", "title": "Strict Filters", @@ -7322,6 +8666,7 @@ "default": "Default" } }, + "additionalProperties": false, "patternProperties": { "^\\$": { "type": "string" @@ -7400,6 +8745,119 @@ } ] }, + "Microsoft.Recognizer": { + "title": "Microsoft Recognizer", + "description": "Union of components which implement the Recognizer abstract class", + "$role": "union", + "oneOf": [ + { + "title": "Microsoft.AdaptiveCardRecognizer", + "description": "Recognizer for detecting the value response from an Adaptive Card.", + "$ref": "#/definitions/Microsoft.AdaptiveCardRecognizer" + }, + { + "title": "Microsoft.CrossTrainedRecognizerSet", + "description": "Recognizer for selecting between cross trained recognizers.", + "$ref": "#/definitions/Microsoft.CrossTrainedRecognizerSet" + }, + { + "title": "Microsoft.LuisRecognizer", + "description": "LUIS recognizer.", + "$ref": "#/definitions/Microsoft.LuisRecognizer" + }, + { + "title": "Microsoft.MultiLanguageRecognizer", + "description": "Configure one recognizer per language and the specify the language fallback policy.", + "$ref": "#/definitions/Microsoft.MultiLanguageRecognizer" + }, + { + "title": "Microsoft.QnAMakerRecognizer", + "description": "Recognizer for generating QnAMatch intents from a KB.", + "$ref": "#/definitions/Microsoft.QnAMakerRecognizer" + }, + { + "title": "Microsoft.RecognizerSet", + "description": "Creates the union of the intents and entities of the recognizers in the set.", + "$ref": "#/definitions/Microsoft.RecognizerSet" + }, + { + "title": "Microsoft.RegexRecognizer", + "description": "Use regular expressions to recognize intents and entities from user input.", + "$ref": "#/definitions/Microsoft.RegexRecognizer" + }, + { + "type": "string", + "title": "string" + } + ] + }, + "Microsoft.RecognizerSet": { + "$role": "union(Microsoft.Recognizer)", + "title": "Recognizer Set", + "description": "Creates the union of the intents and entities of the recognizers in the set.", + "type": "object", + "properties": { + "$kind": { + "title": "$kind", + "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", + "const": "Microsoft.RecognizerSet" + }, + "$copy": { + "title": "$copy", + "description": "Copy the definition by id from a .dialog file.", + "type": "string", + "pattern": "^(([a-zA-Z][a-zA-Z0-9.]*)?(#[a-zA-Z][a-zA-Z0-9.]*)?)$" + }, + "$id": { + "title": "$id", + "description": "Inline id for reuse of an inline definition", + "type": "string", + "pattern": "^([a-zA-Z][a-zA-Z0-9.]*)$" + }, + "$designer": { + "title": "$designer", + "type": "object", + "description": "Extra information for the Bot Framework Designer." + }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional unique id using with RecognizerSet. Other recognizers should return 'DeferToRecognizer_{Id}' intent when cross training data for this recognizer." + }, + "recognizers": { + "type": "array", + "title": "Recognizers", + "description": "List of Recognizers defined for this set.", + "items": { + "$kind": "Microsoft.Recognizer", + "$ref": "#/definitions/Microsoft.Recognizer" + } + } + }, + "additionalProperties": false, + "patternProperties": { + "^\\$": { + "type": "string" + } + }, + "anyOf": [ + { + "title": "Reference", + "required": [ + "$copy" + ] + }, + { + "title": "Type", + "required": [ + "recognizers", + "$kind" + ] + } + ] + }, "Microsoft.RegExEntityRecognizer": { "$role": "union(Microsoft.EntityRecognizers)", "title": "Regex Entity Recognizer", @@ -7465,7 +8923,7 @@ ] }, "Microsoft.RegexRecognizer": { - "$role": "union(Microsoft.IRecognizer)", + "$role": "union(Microsoft.Recognizer)", "title": "Regex recognizer", "description": "Use regular expressions to recognize intents and entities from user input.", "type": "object", @@ -7494,6 +8952,11 @@ "type": "object", "description": "Extra information for the Bot Framework Designer." }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional unique id using with RecognizerSet. Other recognizers should return 'DeferToRecognizer_{Id}' intent when cross training data for this recognizer." + }, "intents": { "type": "array", "title": "RegEx patterns to intents", @@ -7581,8 +9044,24 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "options": { - "type": "object", + "$role": "expression", + "type": [ + "string", + "object" + ], "title": "Options", "description": "One or more options that are passed to the dialog that is called.", "additionalProperties": { @@ -7590,11 +9069,15 @@ "title": "Options" } }, - "includeActivity": { - "type": "boolean", - "title": "Include Activity", - "description": "When set to true, dialog that is called can process the current activity.", - "default": false + "activityProcessed": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Activity Processed", + "description": "When set to false, the dialog that is called can process the current activity.", + "default": true } }, "additionalProperties": false, @@ -7653,8 +9136,22 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "dialog": { "$kind": "Microsoft.IDialog", + "$role": "expression", + "type": "string", "title": "Dialog name", "description": "Name of the dialog to call.", "examples": [ @@ -7663,7 +9160,11 @@ "$ref": "#/definitions/Microsoft.IDialog" }, "options": { - "type": "object", + "$role": "expression", + "type": [ + "string", + "object" + ], "title": "Options", "description": "One or more options that are passed to the dialog that is called.", "additionalProperties": { @@ -7671,11 +9172,15 @@ "title": "Options" } }, - "includeActivity": { - "type": "boolean", - "title": "Include Activity", - "description": "When set to true, dialog that is called can process the current activity.", - "default": false + "activityProcessed": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Activity Processed", + "description": "When set to false, the dialog that is called can process the current activity.", + "default": true } }, "additionalProperties": false, @@ -7734,6 +9239,18 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "activity": { "$kind": "Microsoft.IActivityTemplate", "title": "Activity", @@ -7797,6 +9314,18 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "assignments": { "type": "array", "title": "Assignments", @@ -7806,23 +9335,30 @@ "properties": { "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property (named location to store information).", "examples": [ "user.age" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "New value or expression.", "examples": [ - "'milk'", - "dialog.favColor", - "dialog.favColor == 'red'" - ], - "type": "string" + "='milk'", + "=dialog.favColor", + "=dialog.favColor == 'red'" + ] } } } @@ -7885,25 +9421,44 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property (named location to store information).", "examples": [ "user.age" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "New value or expression.", "examples": [ - "'milk'", - "dialog.favColor", - "dialog.favColor == 'red'" - ], - "type": "string" + "='milk'", + "=dialog.favColor", + "=dialog.favColor == 'red'" + ] } }, "additionalProperties": false, @@ -7929,6 +9484,90 @@ } ] }, + "Microsoft.SignOutUser": { + "$role": "union(Microsoft.IDialog)", + "title": "Sign Out User", + "description": "Sign a user out that was logged in previously using OAuthInput.", + "type": "object", + "properties": { + "$kind": { + "title": "$kind", + "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", + "const": "Microsoft.SignOutUser" + }, + "$copy": { + "title": "$copy", + "description": "Copy the definition by id from a .dialog file.", + "type": "string", + "pattern": "^(([a-zA-Z][a-zA-Z0-9.]*)?(#[a-zA-Z][a-zA-Z0-9.]*)?)$" + }, + "$id": { + "title": "$id", + "description": "Inline id for reuse of an inline definition", + "type": "string", + "pattern": "^([a-zA-Z][a-zA-Z0-9.]*)$" + }, + "$designer": { + "title": "$designer", + "type": "object", + "description": "Extra information for the Bot Framework Designer." + }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional id for the dialog" + }, + "userId": { + "$role": "expression", + "type": "string", + "title": "ActivityId", + "description": "expression to an activityId to get the members. If none is defined then the current activity id will be used.", + "examples": [ + "=$lastActivity" + ] + }, + "connectionName": { + "$role": "expression", + "type": "string", + "title": "Connection Name", + "description": "Connection name that was used with OAuthInput to log a user in." + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + } + }, + "additionalProperties": false, + "patternProperties": { + "^\\$": { + "type": "string" + } + }, + "anyOf": [ + { + "title": "Reference", + "required": [ + "$copy" + ] + }, + { + "title": "Type", + "required": [ + "$kind" + ] + } + ] + }, "Microsoft.StaticActivityTemplate": { "$role": "union(Microsoft.IActivityTemplate)", "title": "Microsoft Static Activity Template", @@ -8024,12 +9663,24 @@ }, "condition": { "$role": "expression", + "type": "string", "title": "Condition", "description": "Property to evaluate.", "examples": [ "user.favColor" + ] + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" ], - "type": "string" + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] }, "cases": { "type": "array", @@ -8044,13 +9695,18 @@ "properties": { "value": { "$role": "expression", + "type": [ + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Value.", "examples": [ "'red'", "dialog.colors.red" - ], - "type": "string" + ] }, "actions": { "type": "array", @@ -8563,6 +10219,12 @@ "$ref": "#/definitions/Microsoft.Test.ITestAction" } }, + "locale": { + "type": "string", + "title": "Locale", + "description": "Set the locale for the user utterances in the script.", + "default": "en-us" + }, "enableTrace": { "type": "boolean", "title": "Enable Trace Activity", @@ -8936,6 +10598,18 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "prompt": { "$kind": "Microsoft.IActivityTemplate", "title": "Initial prompt", @@ -8973,7 +10647,11 @@ "$ref": "#/definitions/Microsoft.IActivityTemplate" }, "maxTurnCount": { - "type": "integer", + "$role": "expression", + "type": [ + "integer", + "string" + ], "title": "Max turn count", "description": "Maximum number of re-prompt attempts to collect information.", "default": 3, @@ -8997,6 +10675,7 @@ }, "property": { "$role": "expression", + "type": "string", "title": "Property", "description": "Property to store collected information. Input will be skipped if property has value (unless 'Always prompt' is true).", "examples": [ @@ -9004,30 +10683,47 @@ "user.name", "conversation.issueTitle", "dialog.favColor" - ], - "type": "string" + ] }, "defaultValue": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Default value", "description": "Expression to examine on each turn of the conversation as possible value to the property.", "examples": [ "@userName", "coalesce(@number, @partySize)" - ], - "type": "string" + ] }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", "description": "Gets or sets a value expression which can be used to intialize the input prompt.", "examples": [ "@userName" - ], - "type": "string" + ] }, "alwaysPrompt": { - "type": "boolean", + "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Always prompt", "description": "Collect information even if the specified 'property' is not empty.", "default": false, @@ -9037,22 +10733,25 @@ }, "allowInterruptions": { "$role": "expression", + "type": [ + "boolean", + "string" + ], "title": "Allow Interruptions", "description": "A boolean expression that determines whether the parent should be allowed to interrupt the input.", "default": "true", "examples": [ "true" - ], - "type": "string" + ] }, "outputFormat": { "$role": "expression", + "type": "string", "title": "Output format", "description": "Expression to format the output.", "examples": [ - "toUpper(this.value)" - ], - "type": "string" + "@{toUpper(this.value)}" + ] } }, "additionalProperties": false, @@ -9169,21 +10868,48 @@ "title": "Id", "description": "Optional id for the dialog" }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, "name": { + "$role": "expression", "type": "string", "title": "Name", "description": "Name of the trace activity" }, + "label": { + "$role": "expression", + "type": "string", + "title": "Label", + "description": "Label for the trace activity (used to identify it in a list of trace activities.)" + }, "valueType": { + "$role": "expression", "type": "string", "title": "Value type", "description": "Type of value" }, "value": { "$role": "expression", + "type": [ + "object", + "array", + "number", + "integer", + "boolean", + "string" + ], "title": "Value", - "description": "Property that holds the value to send as trace activity.", - "type": "string" + "description": "Property that holds the value to send as trace activity." } }, "additionalProperties": false, @@ -9259,6 +10985,91 @@ } ] }, + "Microsoft.UpdateActivity": { + "$role": "union(Microsoft.IDialog)", + "title": "Send an activity", + "description": "Respond with an activity.", + "type": "object", + "properties": { + "$kind": { + "title": "$kind", + "description": "Defines the valid properties for the component you are configuring (from a dialog .schema file)", + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9.]*$", + "const": "Microsoft.UpdateActivity" + }, + "$copy": { + "title": "$copy", + "description": "Copy the definition by id from a .dialog file.", + "type": "string", + "pattern": "^(([a-zA-Z][a-zA-Z0-9.]*)?(#[a-zA-Z][a-zA-Z0-9.]*)?)$" + }, + "$id": { + "title": "$id", + "description": "Inline id for reuse of an inline definition", + "type": "string", + "pattern": "^([a-zA-Z][a-zA-Z0-9.]*)$" + }, + "$designer": { + "title": "$designer", + "type": "object", + "description": "Extra information for the Bot Framework Designer." + }, + "id": { + "type": "string", + "title": "Id", + "description": "Optional id for the dialog" + }, + "disabled": { + "$role": "expression", + "type": [ + "boolean", + "string" + ], + "title": "Disabled", + "description": "Optional condition which if true will disable this action.", + "examples": [ + "user.age > 3" + ] + }, + "activityId": { + "$role": "expression", + "type": "string", + "title": "Activity Id", + "dDescription": "An string expression with the activity id to update.", + "examples": [ + "=dialog.lastActivityId" + ], + "description": "String must contain an expression." + }, + "activity": { + "$kind": "Microsoft.IActivityTemplate", + "title": "Activity", + "description": "Activity to send.", + "$ref": "#/definitions/Microsoft.IActivityTemplate" + } + }, + "additionalProperties": false, + "patternProperties": { + "^\\$": { + "type": "string" + } + }, + "anyOf": [ + { + "title": "Reference", + "required": [ + "$copy" + ] + }, + { + "title": "Type", + "required": [ + "$kind" + ] + } + ] + }, "Microsoft.UrlEntityRecognizer": { "$role": "union(Microsoft.EntityRecognizers)", "title": "Url Entity Recognizer", diff --git a/tests/Microsoft.Bot.Expressions.Tests/BadExpressionTests.cs b/tests/Microsoft.Bot.Expressions.Tests/BadExpressionTests.cs index 0202301bc0..09ee5bf119 100644 --- a/tests/Microsoft.Bot.Expressions.Tests/BadExpressionTests.cs +++ b/tests/Microsoft.Bot.Expressions.Tests/BadExpressionTests.cs @@ -64,7 +64,6 @@ public class BadExpressionTests Test("split(one, 'l')"), // split only accept string parameter Test("split(hello, 1)"), // split only accept string parameter Test("substring(hello, 0.5)"), // the second parameter of substring must be integer - Test("substring(one, 0)"), // the first parameter of substring must be string Test("substring(hello, 10)"), // the start index is out of the range of the string length Test("substring(hello, 0, hello)"), // length is not integer Test("substring(hello, 0, 10)"), // the length of substring is out of the range of the original string @@ -304,7 +303,6 @@ public class BadExpressionTests Test("where(items, item, item2, item3)"), // should have three parameters Test("where(items, add(1), item)"), // Second paramter of where is not an identifier Test("where(items, 1, item)"), // Second paramter error - Test("where(items, x, sum(x))"), // third paramter error Test("indicesAndValues(items, 1)"), // only one param Test("indicesAndValues(1)"), // shoud have array param Test("union(one, two)"), // should have collection param @@ -324,9 +322,9 @@ public class BadExpressionTests Test("sortBy(hello, 'x')"), // first param should be list Test("sortBy(createArray('H','e','l','l','o'), 1)"), // second param should be string Test("sortBy(createArray('H','e','l','l','o'), 'x', hi)"), // second param should be string - #endregion +#endregion - #region Object manipulation and construction functions test +#region Object manipulation and construction functions test Test("json(1,2)"), // should have 1 parameter Test("json(1)"), // should be string parameter Test("json('{\"key1\":value1\"}')"), // invalid json format string @@ -344,28 +342,28 @@ public class BadExpressionTests Test("jPath(hello,'Manufacturers[0].Products[0].Price')"), // not a valid json Test("jPath(hello,'Manufacturers[0]/Products[0]/Price')"), // not a valid path Test("jPath(jsonStr,'$..Products[?(@.Price >= 100)].Name')"), // no matched node - #endregion +#endregion - #region Memory access test +#region Memory access test Test("getProperty(bag, 1)"), // second param should be string Test("Accessor(1)"), // first param should be string Test("Accessor(bag, 1)"), // second should be object Test("one[0]"), // one is not list Test("items[3]"), // index out of range Test("items[one+0.5]"), // index is not integer - #endregion +#endregion - #region Regex +#region Regex Test("isMatch('^[a-z]+$')"), // should have 2 parameter Test("isMatch('abC', one)"), // second param should be string Test("isMatch(1, '^[a-z]+$')"), // first param should be string Test("isMatch('abC', '^[a-z+$')"), // bad regular expression - #endregion +#endregion - #region SetPathToValue tests +#region SetPathToValue tests Test("setPathToValue(2+3, 4)"), // Not a real path Test("setPathToValue(a)") // Missing value - #endregion +#endregion }; /// <summary> @@ -465,7 +463,7 @@ public void Evaluate(string exp) try { var (value, error) = new ExpressionEngine().Parse(exp).TryEvaluate(scope); - if (error == null) + if (error != null) { isFail = true; } @@ -476,10 +474,11 @@ public void Evaluate(string exp) } catch (Exception e) { + isFail = true; TestContext.WriteLine(e.Message); } - if (isFail) + if (isFail == false) { Assert.Fail("Test method did not throw expected exception"); } diff --git a/tests/Microsoft.Bot.Expressions.Tests/ExpressionEngineTests.cs b/tests/Microsoft.Bot.Expressions.Tests/ExpressionEngineTests.cs index cae4379186..5fc979459c 100644 --- a/tests/Microsoft.Bot.Expressions.Tests/ExpressionEngineTests.cs +++ b/tests/Microsoft.Bot.Expressions.Tests/ExpressionEngineTests.cs @@ -808,6 +808,31 @@ public void TestAccumulatePath() Assert.AreEqual(path, "b"); } + [TestMethod] + public void TestTryEvaluateOfT() + { + AssertResult<bool>("true", true); + AssertResult<bool>("false", false); + AssertResult<string>("'this is a test'", "this is a test"); + AssertResult<byte>(byte.MaxValue.ToString(), byte.MaxValue); + AssertResult<short>(short.MaxValue.ToString(), short.MaxValue); + AssertResult<int>(int.MaxValue.ToString(), int.MaxValue); + AssertResult<long>(int.MaxValue.ToString(), int.MaxValue); + AssertResult<ushort>(ushort.MaxValue.ToString(), ushort.MaxValue); + AssertResult<uint>(uint.MaxValue.ToString(), uint.MaxValue); + AssertResult<ulong>(uint.MaxValue.ToString(), uint.MaxValue); + AssertResult<float>(15.32322F.ToString(), 15.32322F); + AssertResult<double>(15.32322.ToString(), 15.32322); + } + + private void AssertResult<T>(string text, T expected) + { + var memory = new object(); + var (result, error) = new ExpressionEngine().Parse(text).TryEvaluate<T>(memory); + Assert.AreEqual(expected, result); + Assert.IsNull(error); + } + private void AssertObjectEquals(object expected, object actual) { if (IsNumber(actual) && IsNumber(expected)) diff --git a/tests/Microsoft.Bot.Expressions.Tests/TriggerTrees/Tests.cs b/tests/Microsoft.Bot.Expressions.Tests/TriggerTrees/Tests.cs index 28c6f9c8fc..beb4a8a776 100644 --- a/tests/Microsoft.Bot.Expressions.Tests/TriggerTrees/Tests.cs +++ b/tests/Microsoft.Bot.Expressions.Tests/TriggerTrees/Tests.cs @@ -192,13 +192,14 @@ public void TestTree() var found = false; foreach (var firstClause in first.Clauses) { - var (value, error) = firstClause.TryEvaluate(memory); - if (error == null && (value is bool match && match)) + var (match, error) = firstClause.TryEvaluate<bool>(memory); + if (error == null && match) { foreach (var secondClause in second.Clauses) { - (value, error) = firstClause.TryEvaluate(memory); - if (error == null && (value is bool match2 && match2)) + bool match2; + (match2, error) = firstClause.TryEvaluate<bool>(memory); + if (error == null && match2) { var reln = firstClause.Relationship(secondClause, tree.Comparers); if (reln == RelationshipType.Equal || reln == RelationshipType.Incomparable)