This commit is contained in:
LocalizationBuildProcess 2019-08-16 15:49:46 -07:00
Родитель 20cbb76f8e
Коммит 99e039563d
108 изменённых файлов: 1308 добавлений и 711 удалений

Просмотреть файл

@ -11,20 +11,29 @@ namespace Microsoft.Bot.Builder.AI.QnA
public class FeedbackRecord
{
/// <summary>
/// User id.
/// Gets or sets user id.
/// </summary>
/// <value>
/// User id.
/// </value>
[JsonProperty("userId")]
public string UserId { get; set; }
/// <summary>
/// User question.
/// Gets or sets user question.
/// </summary>
/// <value>
/// User question.
/// </value>
[JsonProperty("userQuestion")]
public string UserQuestion { get; set; }
/// <summary>
/// QnA Id.
/// Gets or sets qnA Id.
/// </summary>
/// <value>
/// QnA Id.
/// </value>
[JsonProperty("qnaId")]
public int QnaId { get; set; }
}

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.Bot.Builder.AI.QnA
{
private QnAMaker qnamaker;
public QnAMakerDialog(string dialogId = null, QnAMaker qnamaker=null)
public QnAMakerDialog(string dialogId = null, QnAMaker qnamaker = null)
: base(dialogId)
{
this.qnamaker = qnamaker;

Просмотреть файл

@ -42,6 +42,9 @@ namespace Microsoft.Bot.Builder.AI.QnA
/// <summary>
/// Gets or sets qnA Maker options.
/// </summary>
/// <value>
/// QnA Maker options.
/// </value>
public QnAMakerOptions Options { get; set; }
/// <summary>

Просмотреть файл

@ -8,9 +8,10 @@
public class Clause : Expression
{
private Dictionary<string, string> anyBindings = new Dictionary<string, string>();
internal bool Subsumed = false;
private Dictionary<string, string> anyBindings = new Dictionary<string, string>();
internal Clause()
: base(ExpressionType.And)
{

Просмотреть файл

@ -16,7 +16,7 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
/// Optionally rewrite a clause.
/// </summary>
/// <param name="clause">Original clause.</param>
/// <returns></returns>
/// <returns>Optimized clause.</returns>
Clause Optimize(Clause clause);
}

Просмотреть файл

@ -24,6 +24,15 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
private List<Trigger> _triggers = new List<Trigger>();
private List<Node> _specializations = new List<Node>();
private enum Operation
{
None,
Found,
Added,
Removed,
Inserted
}
#if Count
private static int _count = 0;
#endif
@ -31,6 +40,9 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
/// <summary>
/// Gets all of the most specific triggers that contain the <see cref="Clause"/> in this node.
/// </summary>
/// <value>
/// All of the most specific triggers that contain the <see cref="Clause"/> in this node.
/// </value>
public IReadOnlyList<Trigger> Triggers => _triggers;
/// <summary>
@ -42,26 +54,41 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
/// then the second trigger would be in AllTriggers, but not Triggers because it
/// is more general.
/// </remarks>
/// <value>
/// All triggers that contain the <see cref="Clause"/> in this node.
/// </value>
public IReadOnlyList<Trigger> AllTriggers => _allTriggers;
/// <summary>
/// Gets specialized children of this node.
/// </summary>
/// <value>
/// Specialized children of this node.
/// </value>
public IReadOnlyList<Node> Specializations => _specializations;
/// <summary>
/// Gets the logical conjunction this node represents.
/// </summary>
/// <value>
/// The logical conjunction this node represents.
/// </value>
public Clause Clause { get; }
/// <summary>
/// Expression to evaluate for node.
/// Gets expression to evaluate for node.
/// </summary>
/// <value>
/// Expression to evaluate for node.
/// </value>
public Expression Expression { get; }
/// <summary>
/// The tree this node is found in.
/// Gets the tree this node is found in.
/// </summary>
/// <value>
/// The tree this node is found in.
/// </value>
public TriggerTree Tree { get; }
#if TraceTree
@ -120,6 +147,14 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
public void ToString(StringBuilder builder, int indent = 0)
=> Clause.ToString(builder, indent);
/// <summary>
/// Identify the relationship between two nodes.
/// </summary>
/// <param name="other"></param>
/// <returns>Relationship between this node and the other.</returns>
public RelationshipType Relationship(Node other)
=> Clause.Relationship(other.Clause, Tree.Comparers);
/// <summary>
/// Return the most specific matches below this node.
/// </summary>
@ -132,23 +167,6 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
return matches;
}
/// <summary>
/// Identify the relationship between two nodes.
/// </summary>
/// <param name="other"></param>
/// <returns>Relationship between this node and the other.</returns>
public RelationshipType Relationship(Node other)
=> Clause.Relationship(other.Clause, Tree.Comparers);
private enum Operation
{
None,
Found,
Added,
Removed,
Inserted
}
#pragma warning disable IDE0022
internal bool AddNode(Node triggerNode)
{
@ -460,7 +478,6 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
foreach (var removal in removals)
{
// Don't need to add back because specialization already has them
_specializations.Remove(removal);
#if TraceTree
if (Node.ShowTrace)
@ -495,6 +512,7 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
if (!visited.Contains(this))
{
visited.Add(this);
// Remove from allTriggers and triggers
if (_allTriggers.Remove(trigger))
{

Просмотреть файл

@ -9,7 +9,8 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
/// <summary>
/// Type of quantifier for expanding trigger expressions.
/// </summary>
public enum QuantifierType {
public enum QuantifierType
{
/// <summary>
/// Within a clause, duplicate any predicate with variable for each possible binding.
/// </summary>
@ -18,8 +19,8 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
/// <summary>
/// Create a new clause for each possible binding of variable.
/// </summary>
Any }
;
Any
}
/// <summary>
/// Quantifier for allowing runtime expansion of expressions.
@ -27,22 +28,31 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
public class Quantifier
{
/// <summary>
/// Name of variable that will be replaced.
/// Gets name of variable that will be replaced.
/// </summary>
/// <value>
/// Name of variable that will be replaced.
/// </value>
public string Variable { get; }
/// <summary>
/// Type of quantifier.
/// Gets type of quantifier.
/// </summary>
/// <value>
/// Type of quantifier.
/// </value>
public QuantifierType Type { get; }
/// <summary>
/// Possible bindings for quantifier.
/// Gets possible bindings for quantifier.
/// </summary>
/// <value>
/// Possible bindings for quantifier.
/// </value>
public IEnumerable<string> Bindings { get; }
/// <summary>
/// Create a quantifier.
/// Initializes a new instance of the <see cref="Quantifier"/> class.
/// </summary>
/// <param name="variable">Name of variable to replace.</param>
/// <param name="type">Type of quantifier.</param>

Просмотреть файл

@ -20,6 +20,7 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
private List<Clause> _clauses;
/// <summary>
/// Initializes a new instance of the <see cref="Trigger"/> class.
/// Construct a trigger expression.
/// </summary>
/// <param name="tree">Trigger tree that contains this trigger.</param>
@ -49,13 +50,21 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
}
/// <summary>
/// Action to take when trigger is true.
/// Gets action to take when trigger is true.
/// </summary>
/// <value>
/// Action to take when trigger is true.
/// </value>
public object Action { get; }
/// <summary>
/// Expressions are converted into Disjunctive Normal Form where ! is pushed to the leaves and there is an implicit || between clauses and && within a clause.
/// Gets list of expressions converted into Disjunctive Normal Form where ! is pushed to the leaves and
/// there is an implicit || between clauses and &amp;&amp; within a clause.
/// </summary>
/// <value>
/// List of expressions converted into Disjunctive Normal Form where ! is pushed to the leaves and
/// there is an implicit || between clauses and &amp;&amp; within a clause.
/// </value>
public IReadOnlyList<Clause> Clauses => _clauses;
public override string ToString()
@ -102,6 +111,34 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
return result;
}
protected void ToString(StringBuilder builder, int indent = 0)
{
builder.Append(' ', indent);
if (_clauses.Any())
{
var first = true;
foreach (var clause in _clauses)
{
if (first)
{
first = false;
}
else
{
builder.AppendLine();
builder.Append(' ', indent);
builder.Append("|| ");
}
builder.Append(clause.ToString());
}
}
else
{
builder.Append("<Empty>");
}
}
private RelationshipType Relationship(Trigger trigger, Trigger other, Dictionary<string, IPredicateComparer> comparers)
{
var soFar = RelationshipType.Incomparable;
@ -150,34 +187,6 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
return soFar;
}
protected void ToString(StringBuilder builder, int indent = 0)
{
builder.Append(' ', indent);
if (_clauses.Any())
{
var first = true;
foreach (var clause in _clauses)
{
if (first)
{
first = false;
}
else
{
builder.AppendLine();
builder.Append(' ', indent);
builder.Append("|| ");
}
builder.Append(clause.ToString());
}
}
else
{
builder.Append("<Empty>");
}
}
private IEnumerable<Clause> GenerateClauses(Expression expression)
{
switch (expression.Type)

Просмотреть файл

@ -45,16 +45,17 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
/// A trigger tree organizes evaluators according to generalization/specialization in order to make it easier to use rules.
/// </summary>
/// <remarks>
/// A trigger expression generates true if the expression evaluated on a frame is true.
/// The expression itself consists of arbitrary boolean functions ("predicates") combined with && || !.
/// A trigger expression generates true if the expression evaluated on a frame is true.
/// The expression itself consists of arbitrary boolean functions ("predicates") combined with &amp;&amp; || !.
/// Most predicates are expressed over the frame passed in, but they can be anything--there are even ways of optimizing or comparing them.
/// By organizing evaluators into a tree (techinically a DAG) it becomes easier to use rules by reducing the coupling between rules.
/// For example if a rule applies if some predicate A is true, then another rule that applies if A && B are true is
/// By organizing evaluators into a tree (techinically a DAG) it becomes easier to use rules by reducing the coupling between rules.
/// For example if a rule applies if some predicate A is true, then another rule that applies if A &amp;&amp; B are true is
/// more specialized. If the second expression is true, then because we know of the relationship we can ignore the first
/// rule--even though its expression is true. Without this kind of capability in order to add the second rule, you would
/// have to change the first to become A && !B.
/// have to change the first to become A &amp;&amp; !B.
/// </remarks>
[DebuggerDisplay("{ToString()}"), DebuggerTypeProxy(typeof(Debugger))]
[DebuggerDisplay("{ToString()}")]
[DebuggerTypeProxy(typeof(Debugger))]
public class TriggerTree
{
public List<IOptimizer> Optimizers = new List<IOptimizer>();
@ -62,20 +63,6 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
public Node Root;
public int TotalTriggers = 0;
private class Debugger
{
public string TreeString;
public List<IOptimizer> _optimizers;
public Dictionary<string, IPredicateComparer> _comparers;
public Debugger(TriggerTree triggers)
{
TreeString = triggers.TreeToString();
_optimizers = triggers.Optimizers;
_comparers = triggers.Comparers;
}
}
/// <summary>
/// Mark a sub-expression as optional.
/// </summary>
@ -195,17 +182,6 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
return builder.ToString();
}
private void TreeToString(StringBuilder builder, Node node, int indent)
{
node.ToString(builder, indent);
builder.Append($" [{node.Triggers.Count}]");
builder.AppendLine();
foreach (var child in node.Specializations)
{
TreeToString(builder, child, indent + 2);
}
}
public void GenerateGraph(string outPath)
{
using (var output = new StreamWriter(outPath))
@ -217,6 +193,17 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
}
}
private void TreeToString(StringBuilder builder, Node node, int indent)
{
node.ToString(builder, indent);
builder.Append($" [{node.Triggers.Count}]");
builder.AppendLine();
foreach (var child in node.Specializations)
{
TreeToString(builder, child, indent + 2);
}
}
private string NameNode(Node node) => '"' + node.ToString().Replace("\"", "\\\"") + '"';
private void GenerateGraph(StreamWriter output, Node node, int indent, HashSet<Node> visited)
@ -253,7 +240,7 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
/// <summary>
/// Return the possible matches given the current state.
/// </summary>
/// <param name="frame">Frame to evaluate against.</param>
/// <param name="state">State to evaluate against.</param>
/// <returns>Enumeration of possible matches.</returns>
public IEnumerable<Node> Matches(object state) => Root.Matches(state);
@ -294,5 +281,19 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees
return badNode;
}
private class Debugger
{
public string TreeString;
public List<IOptimizer> _optimizers;
public Dictionary<string, IPredicateComparer> _comparers;
public Debugger(TriggerTree triggers)
{
TreeString = triggers.TreeToString();
_optimizers = triggers.Optimizers;
_comparers = triggers.Comparers;
}
}
}
}

Просмотреть файл

@ -109,6 +109,7 @@ namespace Microsoft.Bot.Builder.Azure
if (blob != null)
{
var originalActivity = JsonConvert.DeserializeObject<Activity>(await blob.DownloadTextAsync().ConfigureAwait(false));
// tombstone the original message
var tombstonedActivity = new Activity()
{

Просмотреть файл

@ -16,6 +16,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
{
/// <summary>
/// Action which calls another dialog.
/// </summary>
public abstract class BaseInvokeDialog : DialogAction
{
public BaseInvokeDialog(string dialogIdToCall = null, string property = null, IDictionary<string, string> bindingOptions = null)
@ -37,16 +38,25 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// <summary>
/// Gets or sets configurable options for the dialog.
/// </summary>
/// <value>
/// Configurable options for the dialog.
/// </value>
public object Options { get; set; } = new JObject();
/// <summary>
/// Gets or sets the dialog ID to call.
/// </summary>
/// <value>
/// The dialog ID to call.
/// </value>
public string DialogId { get; set; }
/// <summary>
/// The property from memory to pass to the calling dialog and to set the return value to.
/// Gets or sets the property from memory to pass to the calling dialog and to set the return value to.
/// </summary>
/// <value>
/// The property from memory to pass to the calling dialog and to set the return value to.
/// </value>
public string Property
{
get

Просмотреть файл

@ -25,13 +25,19 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
}
/// <summary>
/// Event name.
/// Gets or sets event name.
/// </summary>
/// <value>
/// Event name.
/// </value>
public string EventName { get; set; }
/// <summary>
/// Event value.
/// Gets or sets event value.
/// </summary>
/// <value>
/// Event value.
/// </value>
public string EventValue { get; set; }
protected override async Task<DialogTurnResult> OnRunCommandAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))

Просмотреть файл

@ -15,8 +15,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
public class DeleteProperty : DialogAction
{
/// <summary>
/// Property to path to remove Example: user.age will remove "age" from "user".
/// Gets or sets property to path to remove Example: user.age will remove "age" from "user".
/// </summary>
/// <value>
/// Property to path to remove Example: user.age will remove "age" from "user".
/// </value>
public string Property { get; set; }
[JsonConstructor]

Просмотреть файл

@ -17,6 +17,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// <summary>
/// Initializes a new instance of the <see cref="EditActions"/> class.
/// </summary>
/// <param name="sourceFilePath"></param>
/// <param name="sourceLineNumber"></param>
[JsonConstructor]
public EditActions([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
: base()
@ -27,12 +29,18 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// <summary>
/// Gets or sets the actions to be applied to the active action.
/// </summary>
/// <value>
/// The actions to be applied to the active action.
/// </value>
[JsonProperty("actions")]
public List<IDialog> Actions { get; set; } = new List<IDialog>();
/// <summary>
/// Gets or sets the type of change to appy to the active actions.
/// </summary>
/// <value>
/// The type of change to appy to the active actions.
/// </value>
[JsonProperty("changeType")]
public ActionChangeType ChangeType { get; set; }

Просмотреть файл

@ -63,6 +63,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// <summary>
/// Gets or sets type of change being applied.
/// </summary>
/// <value>
/// Type of change being applied.
/// </value>
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty("changeType")]
public ArrayChangeType ChangeType { get; set; }
@ -74,7 +77,10 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// <summary>
/// Gets or sets memory expression of the array to manipulate.
/// </summary>Edit
/// </summary>
/// <value>
/// Memory expression of the array to manipulate.
/// </value>Edit
[JsonProperty("arrayProperty")]
public string ArrayProperty
{
@ -85,6 +91,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// <summary>
/// Gets or sets the result of the action.
/// </summary>
/// <value>
/// The result of the action.
/// </value>
[JsonProperty("resultProperty")]
public string ResultProperty
{
@ -95,6 +104,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// <summary>
/// Gets or sets the expression of the item to put onto the array.
/// </summary>
/// <value>
/// The expression of the item to put onto the array.
/// </value>
[JsonProperty("value")]
public string Value
{

Просмотреть файл

@ -29,6 +29,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// <summary>
/// Gets or sets the property to return as the result ending the dialog.
/// </summary>
/// <value>
/// The property to return as the result ending the dialog.
/// </value>
public string ResultProperty { get; set; } = "dialog.result";
protected override async Task<DialogTurnResult> OnRunCommandAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))

Просмотреть файл

@ -54,13 +54,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
return this.Actions;
}
public class ForeachOptions
{
public Expression list { get; set; }
public int offset { get; set; }
}
protected override async Task<DialogTurnResult> OnRunCommandAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
@ -76,8 +69,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
if (options != null && options is ForeachOptions)
{
var opt = options as ForeachOptions;
listProperty = opt.list;
offset = opt.offset;
listProperty = opt.List;
offset = opt.Offset;
}
if (listProperty == null)
@ -107,8 +100,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
DialogId = this.Id,
Options = new ForeachOptions()
{
list = listProperty,
offset = offset + 1
List = listProperty,
Offset = offset + 1
}
});
sc.QueueChanges(changes);
@ -145,5 +138,12 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
return result;
}
public class ForeachOptions
{
public Expression List { get; set; }
public int Offset { get; set; }
}
}
}

Просмотреть файл

@ -22,6 +22,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
{
private Expression listProperty;
[JsonConstructor]
public ForeachPage([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
: base()
{
this.RegisterSourceLocation(sourceFilePath, sourceLineNumber);
}
// Expression used to compute the list that should be enumerated.
[JsonProperty("listProperty")]
public string ListProperty
@ -41,11 +48,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
[JsonProperty("actions")]
public List<IDialog> Actions { get; set; } = new List<IDialog>();
[JsonConstructor]
public ForeachPage([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
: base()
public override List<IDialog> ListDependencies()
{
this.RegisterSourceLocation(sourceFilePath, sourceLineNumber);
return this.Actions;
}
protected override async Task<DialogTurnResult> OnRunCommandAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
@ -64,9 +69,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
if (options != null && options is ForeachPageOptions)
{
var opt = options as ForeachPageOptions;
listProperty = opt.list;
offset = opt.offset;
pageSize = opt.pageSize;
listProperty = opt.List;
offset = opt.Offset;
pageSize = opt.PageSize;
}
if (pageSize == 0)
@ -100,9 +105,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
DialogId = this.Id,
Options = new ForeachPageOptions()
{
list = listProperty,
offset = offset + pageSize,
pageSize = pageSize
List = listProperty,
Offset = offset + pageSize,
PageSize = pageSize
}
});
sc.QueueChanges(changes);
@ -117,6 +122,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
}
}
protected override string OnComputeId()
{
return $"{nameof(Foreach)}({this.ListProperty})";
}
private List<object> GetPage(object list, int index, int pageSize)
{
List<object> page = new List<object>();
@ -142,23 +152,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
return page;
}
protected override string OnComputeId()
{
return $"{nameof(Foreach)}({this.ListProperty})";
}
public override List<IDialog> ListDependencies()
{
return this.Actions;
}
public class ForeachPageOptions
{
public Expression list { get; set; }
public Expression List { get; set; }
public int offset { get; set; }
public int Offset { get; set; }
public int pageSize { get; set; }
public int PageSize { get; set; }
}
}
}

Просмотреть файл

@ -21,7 +21,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// </summary>
public class HttpRequest : DialogAction
{
private static readonly HttpClient client = new HttpClient();
private static readonly HttpClient Client = new HttpClient();
[JsonConstructor]
public HttpRequest([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
public enum ResponseTypes
{
@ -55,13 +62,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
DELETE
}
[JsonConstructor]
public HttpRequest([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
protected override string OnComputeId()
{
return $"HttpRequest[{Method} {Url}]";
@ -84,8 +84,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
public ResponseTypes ResponseType { get; set; } = ResponseTypes.Json;
/// <summary>
/// Property which is bidirectional property for input and output. Example: user.age will be passed in, and user.age will be set when the dialog completes.
/// Gets or sets bidirectional property for input and output. Example: user.age will be passed in, and user.age will be set when the dialog completes.
/// </summary>
/// <value>
/// Property for input and output.
/// </value>
public string Property
{
get
@ -162,7 +165,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
}
// Single command running with a copy of the original data
client.DefaultRequestHeaders.Clear();
Client.DefaultRequestHeaders.Clear();
JToken instanceBody = null;
if (this.Body != null)
@ -186,7 +189,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
{
foreach (var unit in instanceHeaders)
{
client.DefaultRequestHeaders.Add(
Client.DefaultRequestHeaders.Add(
await new TextTemplate(unit.Key).BindToData(dc.Context, dc.State),
await new TextTemplate(unit.Value).BindToData(dc.Context, dc.State));
}
@ -199,11 +202,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
case HttpMethod.POST:
if (instanceBody == null)
{
response = await client.PostAsync(instanceUrl, null);
response = await Client.PostAsync(instanceUrl, null);
}
else
{
response = await client.PostAsync(instanceUrl, new StringContent(instanceBody.ToString(), Encoding.UTF8, "application/json"));
response = await Client.PostAsync(instanceUrl, new StringContent(instanceBody.ToString(), Encoding.UTF8, "application/json"));
}
break;
@ -212,13 +215,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
if (instanceBody == null)
{
var request = new HttpRequestMessage(new System.Net.Http.HttpMethod("PATCH"), instanceUrl);
response = await client.SendAsync(request);
response = await Client.SendAsync(request);
}
else
{
var request = new HttpRequestMessage(new System.Net.Http.HttpMethod("PATCH"), instanceUrl);
request.Content = new StringContent(instanceBody.ToString(), Encoding.UTF8, "application/json");
response = await client.SendAsync(request);
response = await Client.SendAsync(request);
}
break;
@ -226,21 +229,21 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
case HttpMethod.PUT:
if (instanceBody == null)
{
response = await client.PutAsync(instanceUrl, null);
response = await Client.PutAsync(instanceUrl, null);
}
else
{
response = await client.PutAsync(instanceUrl, new StringContent(instanceBody.ToString(), Encoding.UTF8, "application/json"));
response = await Client.PutAsync(instanceUrl, new StringContent(instanceBody.ToString(), Encoding.UTF8, "application/json"));
}
break;
case HttpMethod.DELETE:
response = await client.DeleteAsync(instanceUrl);
response = await Client.DeleteAsync(instanceUrl);
break;
case HttpMethod.GET:
response = await client.GetAsync(instanceUrl);
response = await Client.GetAsync(instanceUrl);
break;
}

Просмотреть файл

@ -22,13 +22,16 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
private Expression condition;
/// <summary>
/// Condition expression against memory Example: "user.age > 18".
/// Gets or sets condition expression against memory. Example: "user.age > 18".
/// </summary>
/// <value>
/// Condition expression against memory.
/// </value>
[JsonProperty("condition")]
public string Condition
{
get { return condition?.ToString(); }
set { lock(this) condition = (value != null) ? new ExpressionEngine().Parse(value) : null; }
set { lock (this) condition = value != null ? new ExpressionEngine().Parse(value) : null; }
}
[JsonProperty("actions")]
@ -44,6 +47,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
this.RegisterSourceLocation(sourceFilePath, sourceLineNumber);
}
public override List<IDialog> ListDependencies()
{
var combined = new List<IDialog>(Actions);
combined.AddRange(ElseActions);
return combined;
}
protected override async Task<DialogTurnResult> OnRunCommandAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
@ -94,12 +104,5 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
var idList = Actions.Select(s => s.Id);
return $"{nameof(IfCondition)}({this.Condition}|{string.Join(",", idList)})";
}
public override List<IDialog> ListDependencies()
{
var combined = new List<IDialog>(Actions);
combined.AddRange(ElseActions);
return combined;
}
}
}

Просмотреть файл

@ -24,8 +24,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
}
/// <summary>
/// Property which is bidirectional property for input and output. Example: user.age will be passed in, and user.age will be set when the dialog completes.
/// Gets or sets bidirectional property for input and output. Example: user.age will be passed in, and user.age will be set when the dialog completes.
/// </summary>
/// <value>
/// Property for input and output.
/// </value>
public string Property
{
get
@ -41,8 +44,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
}
/// <summary>
/// Type, either Array or Object.
/// Gets or sets type, either Array or Object.
/// </summary>
/// <value>
/// Type, either Array or Object.
/// </value>
public string Type { get; set; }
protected override async Task<DialogTurnResult> OnRunCommandAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))

Просмотреть файл

@ -15,18 +15,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// </summary>
public class LogAction : DialogAction
{
/// <summary>
/// LG expression to log.
/// </summary>
[JsonProperty("text")]
public ITextTemplate Text { get; set; }
/// <summary>
/// If set to true a TraceActivity will be sent in addition to console log.
/// </summary>
[JsonProperty("traceActivity")]
public bool TraceActivity { get; set; } = false;
[JsonConstructor]
public LogAction(string text = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
{
@ -37,6 +25,24 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
}
}
/// <summary>
/// Gets or sets lG expression to log.
/// </summary>
/// <value>
/// LG expression to log.
/// </value>
[JsonProperty("text")]
public ITextTemplate Text { get; set; }
/// <summary>
/// Gets or sets a value indicating whether a TraceActivity will be sent in addition to console log.
/// </summary>
/// <value>
/// Whether a TraceActivity will be sent in addition to console log.
/// </value>
[JsonProperty("traceActivity")]
public bool TraceActivity { get; set; } = false;
protected override async Task<DialogTurnResult> OnRunCommandAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
var text = await Text.BindToData(dc.Context, dc.State).ConfigureAwait(false);

Просмотреть файл

@ -15,11 +15,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// </summary>
public class SendActivity : DialogAction
{
/// <summary>
/// Template for the activity.
/// </summary>
public ITemplate<Activity> Activity { get; set; }
[JsonConstructor]
public SendActivity(string text = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
{
@ -27,6 +22,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
this.Activity = new ActivityTemplate(text ?? string.Empty);
}
/// <summary>
/// Gets or sets template for the activity.
/// </summary>
/// <value>
/// Template for the activity.
/// </value>
public ITemplate<Activity> Activity { get; set; }
public SendActivity(Activity activity, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
{
this.RegisterSourceLocation(callerPath, callerLine);
@ -57,7 +60,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
private static string Ellipsis(string text, int length)
{
if (text.Length <= length) return text;
if (text.Length <= length) { return text; }
int pos = text.IndexOf(" ", length);
if (pos >= 0)

Просмотреть файл

@ -28,8 +28,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
}
/// <summary>
/// Value expression.
/// Gets or sets value expression.
/// </summary>
/// <value>
/// Value expression.
/// </value>
[JsonProperty("value")]
public string Value
{
@ -38,8 +41,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
}
/// <summary>
/// Property to put the value in.
/// Gets or sets property to put the value in.
/// </summary>
/// <value>
/// Property to put the value in.
/// </value>
[JsonProperty("property")]
public string Property
{

Просмотреть файл

@ -15,57 +15,6 @@ using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
{
public class Case
{
public Case(string value = null, IEnumerable<IDialog> actions = null)
{
this.Value = value;
this.Actions = actions?.ToList() ?? this.Actions;
}
/// <summary>
/// Value expression to be compared against condition.
/// </summary>
[JsonProperty("value")]
public string Value { get; set; }
/// <summary>
/// Set of actions to be executed given that the condition of the switch matches the value of this case.
/// </summary>
[JsonProperty("actions")]
public List<IDialog> Actions { get; set; } = new List<IDialog>();
/// <summary>
/// Creates an expression that returns the value in its primitive type. Still
/// assumes that switch case values are compile time constants and not expressions
/// that can be evaluated against state.
/// </summary>
/// <returns>An expression that reflects the constant case value.</returns>
public Expression CreateValueExpression()
{
Expression expression = null;
if (Int64.TryParse(Value, out Int64 i))
{
expression = Expression.ConstantExpression(i);
}
else if (float.TryParse(Value, out float f))
{
expression = Expression.ConstantExpression(f);
}
else if (bool.TryParse(Value, out bool b))
{
expression = Expression.ConstantExpression(b);
}
else
{
expression = Expression.ConstantExpression(Value);
}
return expression;
}
}
/// <summary>
/// Conditional branch with multiple cases.
/// </summary>
@ -75,9 +24,19 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
private Expression condition;
[JsonConstructor]
public SwitchCondition([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Condition expression against memory Example: "user.age > 18".
/// Gets or sets condition expression against memory Example: "user.age > 18".
/// </summary>
/// <value>
/// Condition expression against memory Example: "user.age > 18".
/// </value>
[JsonProperty("condition")]
public string Condition
{
@ -91,17 +50,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
public List<Case> Cases = new List<Case>();
/// <summary>
/// Default case.
/// Gets or sets default case.
/// </summary>
/// <value>
/// Default case.
/// </value>
public List<IDialog> Default { get; set; } = new List<IDialog>();
[JsonConstructor]
public SwitchCondition([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
protected override async Task<DialogTurnResult> OnRunCommandAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
@ -195,4 +150,61 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
return dialogs;
}
}
public class Case
{
public Case(string value = null, IEnumerable<IDialog> actions = null)
{
this.Value = value;
this.Actions = actions?.ToList() ?? this.Actions;
}
/// <summary>
/// Gets or sets value expression to be compared against condition.
/// </summary>
/// <value>
/// Value expression to be compared against condition.
/// </value>
[JsonProperty("value")]
public string Value { get; set; }
/// <summary>
/// Gets or sets set of actions to be executed given that the condition of the switch matches the value of this case.
/// </summary>
/// <value>
/// Set of actions to be executed given that the condition of the switch matches the value of this case.
/// </value>
[JsonProperty("actions")]
public List<IDialog> Actions { get; set; } = new List<IDialog>();
/// <summary>
/// Creates an expression that returns the value in its primitive type. Still
/// assumes that switch case values are compile time constants and not expressions
/// that can be evaluated against state.
/// </summary>
/// <returns>An expression that reflects the constant case value.</returns>
public Expression CreateValueExpression()
{
Expression expression = null;
if (Int64.TryParse(Value, out Int64 i))
{
expression = Expression.ConstantExpression(i);
}
else if (float.TryParse(Value, out float f))
{
expression = Expression.ConstantExpression(f);
}
else if (bool.TryParse(Value, out bool b))
{
expression = Expression.ConstantExpression(b);
}
else
{
expression = Expression.ConstantExpression(Value);
}
return expression;
}
}
}

Просмотреть файл

@ -16,27 +16,36 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
/// </summary>
public class TraceActivity : DialogAction
{
/// <summary>
/// Name of the trace activity.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Value type of the trace activity.
/// </summary>
public string ValueType { get; set; }
/// <summary>
/// Property binding to memory to send as the value.
/// </summary>
public string Value { get; set; }
[JsonConstructor]
public TraceActivity([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
{
this.RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets name of the trace activity.
/// </summary>
/// <value>
/// Name of the trace activity.
/// </value>
public string Name { get; set; }
/// <summary>
/// Gets or sets value type of the trace activity.
/// </summary>
/// <value>
/// Value type of the trace activity.
/// </value>
public string ValueType { get; set; }
/// <summary>
/// Gets or sets property binding to memory to send as the value.
/// </summary>
/// <value>
/// Property binding to memory to send as the value.
/// </value>
public string Value { get; set; }
protected override async Task<DialogTurnResult> OnRunCommandAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)

Просмотреть файл

@ -35,37 +35,55 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
public IStatePropertyAccessor<Dictionary<string, object>> UserState { get; set; }
/// <summary>
/// Recognizer for processing incoming user input.
/// Gets or sets recognizer for processing incoming user input.
/// </summary>
/// <value>
/// Recognizer for processing incoming user input.
/// </value>
public IRecognizer Recognizer { get; set; }
/// <summary>
/// Language Generator override.
/// Gets or sets language Generator override.
/// </summary>
/// <value>
/// Language Generator override.
/// </value>
public ILanguageGenerator Generator { get; set; }
/// <summary>
/// Rules for handling events to dynamic modifying the executing plan.
/// Gets or sets rules for handling events to dynamic modifying the executing plan.
/// </summary>
/// <value>
/// Rules for handling events to dynamic modifying the executing plan.
/// </value>
public virtual List<IOnEvent> Events { get; set; } = new List<IOnEvent>();
/// <summary>
/// Gets or sets the policty to Automatically end the dialog when there are no actions to execute.
/// Gets or sets a value indicating whether gets or sets the policty to Automatically end the dialog when there are no actions to execute.
/// </summary>
/// <remarks>
/// If true, when there are no actions to execute the current dialog will end
/// If false, when there are no actions to execute the current dialog will simply end the turn and still be active.
/// </remarks>
/// <value>
/// The policty to Automatically end the dialog when there are no actions to execute.
/// </value>
public bool AutoEndDialog { get; set; } = true;
/// <summary>
/// Gets or sets the selector for picking the possible events to execute.
/// </summary>
/// <value>
/// The selector for picking the possible events to execute.
/// </value>
public IEventSelector Selector { get; set; }
/// <summary>
/// Gets or sets the property to return as the result when the dialog ends when there are no more Actions and AutoEndDialog = true.
/// </summary>
/// <value>
/// The property to return as the result when the dialog ends when there are no more Actions and AutoEndDialog = true.
/// </value>
public string DefaultResultProperty { get; set; } = "dialog.result";
public override IBotTelemetryClient TelemetryClient
@ -440,6 +458,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
if (Recognizer != null)
{
var result = await Recognizer.RecognizeAsync(context, cancellationToken).ConfigureAwait(false);
// only allow one intent
var topIntent = result.GetTopScoringIntent();
result.Intents.Clear();

Просмотреть файл

@ -17,21 +17,26 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
public class OnActivity : OnDialogEvent
{
[JsonConstructor]
public OnActivity(string type=null, List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(events: new List<string>()
{
AdaptiveEvents.ActivityReceived
},
actions: actions,
constraint: constraint,
callerPath: callerPath, callerLine: callerLine)
public OnActivity(string type = null, List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(
events: new List<string>()
{
AdaptiveEvents.ActivityReceived
},
actions: actions,
constraint: constraint,
callerPath: callerPath,
callerLine: callerLine)
{
Type = type;
}
/// <summary>
/// ActivityType.
/// Gets or sets activityType.
/// </summary>
/// <value>
/// ActivityType.
/// </value>
[JsonProperty("type")]
public string Type { get; set; }

Просмотреть файл

@ -15,13 +15,15 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
{
[JsonConstructor]
public OnBeginDialog(List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(events: new List<string>()
{
: base(
events: new List<string>()
{
AdaptiveEvents.BeginDialog
},
actions: actions,
constraint: constraint,
callerPath: callerPath, callerLine: callerLine)
},
actions: actions,
constraint: constraint,
callerPath: callerPath,
callerLine: callerLine)
{
}
}

Просмотреть файл

@ -14,7 +14,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
public class OnConversationUpdateActivity : OnActivity
{
[JsonConstructor]
public OnConversationUpdateActivity(List<IDialog> actions = null, string constraint= null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(type: ActivityTypes.ConversationUpdate, actions: actions, constraint: constraint, callerPath: callerPath, callerLine: callerLine) { }
public OnConversationUpdateActivity(List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(type: ActivityTypes.ConversationUpdate, actions: actions, constraint: constraint, callerPath: callerPath, callerLine: callerLine)
{
}
}
}

Просмотреть файл

@ -13,11 +13,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
/// </summary>
public class OnDialogEvent : OnEvent
{
/// <summary>
/// List of events to filter.
/// </summary>
public List<string> Events { get; set; }
[JsonConstructor]
public OnDialogEvent(List<string> events = null, List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(constraint: constraint, actions: actions, callerPath: callerPath, callerLine: callerLine)
@ -26,6 +21,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
this.Actions = actions ?? new List<IDialog>();
}
/// <summary>
/// Gets or sets list of events to filter.
/// </summary>
/// <value>
/// List of events to filter.
/// </value>
public List<string> Events { get; set; }
protected override ActionChangeList OnCreateChangeList(SequenceContext planning, object dialogOptions = null)
{
var changeList = new ActionChangeList()

Просмотреть файл

@ -14,7 +14,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
public class OnEndOfConversationActivity : OnActivity
{
[JsonConstructor]
public OnEndOfConversationActivity(List<IDialog> actions = null, string constraint= null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
public OnEndOfConversationActivity(List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(type: ActivityTypes.EndOfConversation, actions: actions, constraint: constraint, callerPath: callerPath, callerLine: callerLine) { }
}
}

Просмотреть файл

@ -40,12 +40,18 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
/// <summary>
/// Gets or sets the constraint to apply to the rule (OPTIONAL).
/// </summary>
/// <value>
/// The constraint to apply to the rule (OPTIONAL).
/// </value>
[JsonProperty("constraint")]
public string Constraint { get; set; }
/// <summary>
/// Gets or sets the actions to add to the plan when the rule constraints are met.
/// </summary>
/// <value>
/// The actions to add to the plan when the rule constraints are met.
/// </value>
[JsonProperty("actions")]
public List<IDialog> Actions { get; set; } = new List<IDialog>();

Просмотреть файл

@ -14,7 +14,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
public class OnEventActivity : OnActivity
{
[JsonConstructor]
public OnEventActivity(List<IDialog> actions = null, string constraint= null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
public OnEventActivity(List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(type: ActivityTypes.Event, actions: actions, constraint: constraint, callerPath: callerPath, callerLine: callerLine) { }
}
}

Просмотреть файл

@ -14,7 +14,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
public class OnHandoffActivity : OnActivity
{
[JsonConstructor]
public OnHandoffActivity(List<IDialog> actions = null, string constraint= null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
public OnHandoffActivity(List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(type: ActivityTypes.Handoff, actions: actions, constraint: constraint, callerPath: callerPath, callerLine: callerLine) { }
}
}

Просмотреть файл

@ -31,12 +31,18 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
/// <summary>
/// Gets or sets intent to match on.
/// </summary>
/// <value>
/// Intent to match on.
/// </value>
[JsonProperty("intent")]
public string Intent { get; set; }
/// <summary>
/// Gets or sets entities which must be recognized for this rule to trigger.
/// </summary>
/// <value>
/// Entities which must be recognized for this rule to trigger.
/// </value>
[JsonProperty("entities")]
public List<string> Entities { get; set; }
@ -74,7 +80,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
Turn = new Dictionary<string, object>()
{
{ "recognized" , JObject.FromObject(new
{
"recognized" , JObject.FromObject(new
{
text = recognizerResult.Text,
alteredText = recognizerResult.AlteredText,

Просмотреть файл

@ -14,7 +14,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
public class OnInvokeActivity : OnActivity
{
[JsonConstructor]
public OnInvokeActivity(List<IDialog> actions = null, string constraint= null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
public OnInvokeActivity(List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(type: ActivityTypes.Invoke, actions: actions, constraint: constraint, callerPath: callerPath, callerLine: callerLine) { }
}
}

Просмотреть файл

@ -14,7 +14,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
public class OnMessageActivity : OnActivity
{
[JsonConstructor]
public OnMessageActivity(List<IDialog> actions = null, string constraint= null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
public OnMessageActivity(List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(type: ActivityTypes.Message, actions: actions, constraint: constraint, callerPath: callerPath, callerLine: callerLine) { }
}
}

Просмотреть файл

@ -14,7 +14,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
public class OnMessageDeleteActivity : OnActivity
{
[JsonConstructor]
public OnMessageDeleteActivity(List<IDialog> actions = null, string constraint= null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
public OnMessageDeleteActivity(List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(type: ActivityTypes.MessageDelete, actions: actions, constraint: constraint, callerPath: callerPath, callerLine: callerLine) { }
}
}

Просмотреть файл

@ -14,7 +14,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
public class OnMessageReactionActivity : OnActivity
{
[JsonConstructor]
public OnMessageReactionActivity(List<IDialog> actions = null, string constraint= null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
public OnMessageReactionActivity(List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(type: ActivityTypes.MessageReaction, actions: actions, constraint: constraint, callerPath: callerPath, callerLine: callerLine) { }
}
}

Просмотреть файл

@ -14,7 +14,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
public class OnMessageUpdateActivity : OnActivity
{
[JsonConstructor]
public OnMessageUpdateActivity(List<IDialog> actions = null, string constraint= null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
public OnMessageUpdateActivity(List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(type: ActivityTypes.MessageUpdate, actions: actions, constraint: constraint, callerPath: callerPath, callerLine: callerLine) { }
}
}

Просмотреть файл

@ -14,7 +14,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Events
public class OnTypingActivity : OnActivity
{
[JsonConstructor]
public OnTypingActivity(List<IDialog> actions = null, string constraint= null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
public OnTypingActivity(List<IDialog> actions = null, string constraint = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base(type: ActivityTypes.Typing, actions: actions, constraint: constraint, callerPath: callerPath, callerLine: callerLine) { }
}
}

Просмотреть файл

@ -24,8 +24,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
Task<List<ActionChangeList>> ExecuteAsync(SequenceContext context);
/// <summary>
/// Actions to add to the plan when the rule is activated.
/// Gets actions to add to the plan when the rule is activated.
/// </summary>
/// <value>
/// Actions to add to the plan when the rule is activated.
/// </value>
List<IDialog> Actions { get; }
}
}

Просмотреть файл

@ -52,38 +52,59 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
};
/// <summary>
/// List of choices to present to user.
/// Gets or sets list of choices to present to user.
/// </summary>
/// <value>
/// List of choices to present to user.
/// </value>
public List<Choice> Choices { get; set; }
/// <summary>
/// Expression collection of choices to present o user.
/// Gets or sets expression collection of choices to present o user.
/// </summary>
/// <value>
/// Expression collection of choices to present o user.
/// </value>
public string ChoicesProperty { get; set; }
/// <summary>
/// ListStyle to use to render the choices.
/// Gets or sets listStyle to use to render the choices.
/// </summary>
/// <value>
/// ListStyle to use to render the choices.
/// </value>
public ListStyle Style { get; set; } = ListStyle.Auto;
/// <summary>
/// DefaultLocale.
/// Gets or sets defaultLocale.
/// </summary>
/// <value>
/// DefaultLocale.
/// </value>
public string DefaultLocale { get; set; } = null;
/// <summary>
/// Control the format of the response (value or the index of the choice).
/// Gets or sets control the format of the response (value or the index of the choice).
/// </summary>
/// <value>
/// Control the format of the response (value or the index of the choice).
/// </value>
public ChoiceOutputFormat OutputFormat { get; set; } = ChoiceOutputFormat.Value;
/// <summary>
/// ChoiceOptions controls display options for customizing language.
/// Gets or sets choiceOptions controls display options for customizing language.
/// </summary>
/// <value>
/// ChoiceOptions controls display options for customizing language.
/// </value>
public ChoiceFactoryOptions ChoiceOptions { get; set; } = null;
/// <summary>
/// Customize how to use the choices to recognize the response from the user.
/// Gets or sets customize how to use the choices to recognize the response from the user.
/// </summary>
/// <value>
/// Customize how to use the choices to recognize the response from the user.
/// </value>
public FindChoicesOptions RecognizerOptions { get; set; } = null;
public ChoiceInput([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)

Просмотреть файл

@ -55,8 +55,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
public AllowInterruptions AllowInterruptions { get; set; } = AllowInterruptions.NotRecognized;
/// <summary>
/// Initial value for the prompt.
/// Gets or sets initial value for the prompt.
/// </summary>
/// <value>
/// Initial value for the prompt.
/// </value>
[JsonProperty("value")]
public string Value
{
@ -65,30 +68,45 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
}
/// <summary>
/// Activity to send to the user.
/// Gets or sets activity to send to the user.
/// </summary>
/// <value>
/// Activity to send to the user.
/// </value>
public ITemplate<Activity> Prompt { get; set; }
/// <summary>
/// Activity template for retrying prompt.
/// Gets or sets activity template for retrying prompt.
/// </summary>
/// <value>
/// Activity template for retrying prompt.
/// </value>
public ITemplate<Activity> UnrecognizedPrompt { get; set; }
/// <summary>
/// Activity template to send to the user whenever the value provided is invalid.
/// Gets or sets activity template to send to the user whenever the value provided is invalid.
/// </summary>
/// <value>
/// Activity template to send to the user whenever the value provided is invalid.
/// </value>
public ITemplate<Activity> InvalidPrompt { get; set; }
public List<string> Validations { get; set; } = new List<string>();
/// <summary>
/// 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 dilog gives up.
/// </summary>
/// <value>
/// Maximum number of times to ask the user for this value before the dilog gives up.
/// </value>
public int? MaxTurnCount { get; set; }
/// <summary>
/// Default value for the input dialog.
/// Gets or sets default value for the input dialog.
/// </summary>
/// <value>
/// Default value for the input dialog.
/// </value>
public string DefaultValue
{
get { return defaultValue?.ToString(); }
@ -96,8 +114,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
}
/// <summary>
/// The property from memory to pass to the calling dialog and to set the return value to.
/// Gets or sets the property from memory to pass to the calling dialog and to set the return value to.
/// </summary>
/// <value>
/// The property from memory to pass to the calling dialog and to set the return value to.
/// </value>
public string Property
{
get

Просмотреть файл

@ -49,8 +49,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
public int Timeout { get; set; } = 900000;
/// <summary>
/// The property from memory to pass to the calling dialog and to set the return value to.
/// Gets or sets the property from memory to pass to the calling dialog and to set the return value to.
/// </summary>
/// <value>
/// The property from memory to pass to the calling dialog and to set the return value to.
/// </value>
public string Property
{
get

Просмотреть файл

@ -14,14 +14,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Recognizers
public class MultiLanguageRecognizer : IRecognizer
{
/// <summary>
/// Policy for languages fallback.
/// Gets or sets policy for languages fallback.
/// </summary>
/// <value>
/// Policy for languages fallback.
/// </value>
[JsonProperty("languagePolicy")]
public ILanguagePolicy LanguagePolicy { get; set; } = new LanguagePolicy();
/// <summary>
/// Map of languages -> IRecognizer.
/// Gets or sets map of languages -> IRecognizer.
/// </summary>
/// <value>
/// Map of languages -> IRecognizer.
/// </value>
[JsonProperty("recognizers")]
public IDictionary<string, IRecognizer> Recognizers { get; set; } = new Dictionary<string, IRecognizer>();

Просмотреть файл

@ -22,8 +22,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Recognizers
private Dictionary<string, Regex> patterns = new Dictionary<string, Regex>();
/// <summary>
/// Dictionary of patterns -> Intent names.
/// Gets or sets dictionary of patterns -> Intent names.
/// </summary>
/// <value>
/// Dictionary of patterns -> Intent names.
/// </value>
[JsonProperty("intents")]
public Dictionary<string, string> Intents { get; set; } = new Dictionary<string, string>();

Просмотреть файл

@ -19,8 +19,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Selectors
private Expression condition;
/// <summary>
/// Expression that determines which selector to use.
/// Gets or sets expression that determines which selector to use.
/// </summary>
/// <value>
/// Expression that determines which selector to use.
/// </value>
public string Condition
{
get { return condition?.ToString(); }
@ -28,13 +31,19 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Selectors
}
/// <summary>
/// Selector if <see cref="Condition"/> is true.
/// Gets or sets selector if <see cref="Condition"/> is true.
/// </summary>
/// <value>
/// Selector if <see cref="Condition"/> is true.
/// </value>
public IEventSelector IfTrue { get; set; }
/// <summary>
/// Selector if <see cref="Condition"/> is false.
/// Gets or sets selector if <see cref="Condition"/> is false.
/// </summary>
/// <value>
/// Selector if <see cref="Condition"/> is false.
/// </value>
public IEventSelector IfFalse { get; set; }
public void Initialize(IEnumerable<IOnEvent> rules, bool evaluate = true)

Просмотреть файл

@ -16,8 +16,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Selectors
private readonly TriggerTree _tree = new TriggerTree();
/// <summary>
/// Optional rule selector to use when more than one most specific rule is true.
/// Gets or sets optional rule selector to use when more than one most specific rule is true.
/// </summary>
/// <value>
/// Optional rule selector to use when more than one most specific rule is true.
/// </value>
public IEventSelector Selector { get; set; }
public void Initialize(IEnumerable<IOnEvent> rules, bool evaluate)

Просмотреть файл

@ -20,9 +20,12 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Selectors
private IExpressionParser _parser = new ExpressionEngine();
/// <summary>
/// Optional seed for random number generator.
/// Gets or sets optional seed for random number generator.
/// </summary>
/// <remarks>If not specified a random seed will be used.</remarks>
/// <value>
/// Optional seed for random number generator.
/// </value>
public int Seed
{
get => _seed;

Просмотреть файл

@ -23,13 +23,19 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
public AdaptiveDialogState Plans { get; private set; }
/// <summary>
/// Gets or sets list of actions being executed.
/// </summary>
/// <value>
/// List of actions being executed.
/// </summary>
/// </value>
public List<ActionState> Actions { get; set; }
/// <summary>
/// List of changes that are queued to be applied.
/// Gets list of changes that are queued to be applied.
/// </summary>
/// <value>
/// List of changes that are queued to be applied.
/// </value>
public List<ActionChangeList> Changes
{
get { return this.Context.TurnState.Get<List<ActionChangeList>>(changeKey); }
@ -340,6 +346,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
/// <summary>
/// Gets or sets turn state associated with the plan change list (it will be applied to turn state when plan is applied).
/// </summary>
/// <value>
/// Turn state associated with the plan change list (it will be applied to turn state when plan is applied).
/// </value>
[JsonProperty(PropertyName = "turn")]
public Dictionary<string, object> Turn { get; set; }
}

Просмотреть файл

@ -14,8 +14,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Composition.Recognizers
public EntityRecognizerSet() { }
/// <summary>
/// Recognizer pool.
/// Gets or sets recognizer pool.
/// </summary>
/// <value>
/// Recognizer pool.
/// </value>
public IList<IEntityRecognizer> Recognizers { get; set; } = new List<IEntityRecognizer>();
/// <summary>
@ -68,7 +71,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Composition.Recognizers
// switch to next pool of new entities to process
entitiesToProcess = newEntitiesToProcess;
} while (entitiesToProcess.Count > 0);
}
while (entitiesToProcess.Count > 0);
return allNewEntities;
}

Просмотреть файл

@ -1,4 +1,5 @@

//using System;
//using System.Threading.Tasks;

Просмотреть файл

@ -38,7 +38,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Debugging
listener.Start();
using (cancellationToken.Register(listener.Stop))
{
var local = (IPEndPoint) listener.LocalEndpoint;
var local = (IPEndPoint)listener.LocalEndpoint;
// output is parsed on launch by "vscode-dialog-debugger\src\ts\extension.ts"
Console.WriteLine($"{nameof(DebugTransport)}\t{local.Address}\t{local.Port}");

Просмотреть файл

@ -7,8 +7,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Declarative.Parsers
{
public static class TemplateExpressionParser
{
private static readonly Regex funcRegex = new Regex(@"{\b[^()]+\((.*)\)}$", RegexOptions.Compiled);
private static readonly Regex argsRegex = new Regex(@"([^,]+\(.+?\))|([^,]+)", RegexOptions.Compiled);
private static readonly Regex FuncRegex = new Regex(@"{\b[^()]+\((.*)\)}$", RegexOptions.Compiled);
private static readonly Regex ArgsRegex = new Regex(@"([^,]+\(.+?\))|([^,]+)", RegexOptions.Compiled);
// Receives expression of the form: {<func>(<arg1>, <arg2>, <argn>)}
// and returns an object containig the values <func> and a collection of
@ -20,7 +20,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Declarative.Parsers
throw new ArgumentException(nameof(template));
}
var func = funcRegex.Match(template);
var func = FuncRegex.Match(template);
string innerArgs = func?.Groups?[1]?.Value;
@ -29,7 +29,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Declarative.Parsers
throw new ArgumentException(nameof(template), "Expected function format {<func>(<arg1>, <arg2>, <argn>)}");
}
var paramTags = argsRegex.Matches(innerArgs);
var paramTags = ArgsRegex.Matches(innerArgs);
var paramsList = new List<string>();

Просмотреть файл

@ -105,8 +105,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Declarative.Resources
}
/// <summary>
/// folder to enumerate.
/// Gets or sets folder to enumerate.
/// </summary>
/// <value>
/// folder to enumerate.
/// </value>
public DirectoryInfo Directory { get; set; }
public bool IncludeSubFolders { get; set; }

Просмотреть файл

@ -9,8 +9,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Declarative.Resources
public interface IResource
{
/// <summary>
/// Resource name.
/// Gets resource name.
/// </summary>
/// <value>
/// Resource name.
/// </value>
string Id { get; }
/// <summary>

Просмотреть файл

@ -7,8 +7,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Declarative.Resources
public interface IResourceProvider
{
/// <summary>
/// id for the resource provider.
/// Gets id for the resource provider.
/// </summary>
/// <value>
/// id for the resource provider.
/// </value>
string Id { get; }
event ResourceChangedEventHandler Changed;

Просмотреть файл

@ -11,6 +11,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Debugging
{
public static class Source
{
public interface IRegistry
{
void Add(object item, Range range);
bool TryGetValue(object item, out Range range);
}
public struct Point
{
public int LineIndex { get; set; }
@ -41,13 +48,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Debugging
public override string ToString() => $"{LineIndex}:{CharIndex}";
}
public interface IRegistry
{
void Add(object item, Range range);
bool TryGetValue(object item, out Range range);
}
public sealed class Range
{
public string Path { get; set; }

Просмотреть файл

@ -34,8 +34,11 @@ namespace Microsoft.Bot.Builder.Dialogs
}
/// <summary>
/// Unique id for the dialog.
/// Gets or sets id for the dialog.
/// </summary>
/// <value>
/// Id for the dialog.
/// </value>
public string Id
{
get
@ -51,18 +54,27 @@ namespace Microsoft.Bot.Builder.Dialogs
}
/// <summary>
/// Set of tags assigned to the dialog.
/// Gets set of tags assigned to the dialog.
/// </summary>
/// <value>
/// Set of tags assigned to the dialog.
/// </value>
public List<string> Tags { get; private set; } = new List<string>();
/// <summary>
/// Gets or sets expression for the memory slots to bind the dialogs options to on a call to `beginDialog()`.
/// </summary>
/// <value>
/// Expression for the memory slots to bind the dialogs options to on a call to `beginDialog()`.
/// </value>
public Dictionary<string, string> InputBindings { get; set; } = new Dictionary<string, string>();
/// <summary>
/// Gets or sets jSONPath expression for the memory slot to bind the dialogs result to when `endDialog()` is called.
/// </summary>
/// <value>
/// JSONPath expression for the memory slot to bind the dialogs result to when `endDialog()` is called.
/// </value>
public string OutputBinding { get; set; }
/// <summary>
@ -195,6 +207,7 @@ namespace Microsoft.Bot.Builder.Dialogs
/// </remarks>
/// <param name="dc">The dialog context for the current turn of conversation.</param>
/// <param name="e">The event being raised.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns> Whether the event is handled by the current dialog and further processing should stop.</returns>
protected virtual Task<bool> OnPreBubbleEvent(DialogContext dc, DialogEvent e, CancellationToken cancellationToken)
{
@ -210,6 +223,7 @@ namespace Microsoft.Bot.Builder.Dialogs
/// </remarks>
/// <param name="dc">The dialog context for the current turn of conversation.</param>
/// <param name="e">The event being raised.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns> Whether the event is handled by the current dialog and further processing should stop.</returns>
protected virtual Task<bool> OnPostBubbleEvent(DialogContext dc, DialogEvent e, CancellationToken cancellationToken)
{

Просмотреть файл

@ -12,7 +12,7 @@ namespace Microsoft.Bot.Builder.Dialogs
{
public abstract class DialogContainer : Dialog
{
protected readonly DialogSet _dialogs = new DialogSet();
private readonly DialogSet _dialogs = new DialogSet();
public DialogContainer(string dialogId = null)
: base(dialogId)

Просмотреть файл

@ -23,9 +23,18 @@ namespace Microsoft.Bot.Builder.Dialogs
/// Initializes a new instance of the <see cref="DialogContext"/> class.
/// </summary>
/// <param name="dialogs">Parent dialog set.</param>
/// <param name="turnContext">Context for the current turn of conversation with the user.</param>
/// <param name="parentDialogContext">Parent dialog state.</param>
/// <param name="state">Current dialog state.</param>
public DialogContext(DialogSet dialogs, DialogContext parentDialogContext, DialogState state, IDictionary<string, object> conversationState = null, IDictionary<string, object> userState = null, IDictionary<string, object> settings = null)
/// <param name="conversationState">Context for the current turn of conversation with the user.</param>
/// <param name="userState">Context for the user state.</param>
/// <param name="settings">Settings state.</param>
public DialogContext(
DialogSet dialogs,
DialogContext parentDialogContext,
DialogState state,
IDictionary<string, object> conversationState = null,
IDictionary<string, object> userState = null,
IDictionary<string, object> settings = null)
{
Dialogs = dialogs;
Parent = parentDialogContext ?? throw new ArgumentNullException(nameof(parentDialogContext));
@ -64,36 +73,51 @@ namespace Microsoft.Bot.Builder.Dialogs
}
/// <summary>
/// Parent context.
/// Gets or sets parent context.
/// </summary>
/// <value>
/// Parent context.
/// </value>
public DialogContext Parent { get; set; }
/// <summary>
/// Set of dialogs which are active for the current dialog container.
/// Gets set of dialogs which are active for the current dialog container.
/// </summary>
/// <value>
/// Set of dialogs which are active for the current dialog container.
/// </value>
public DialogSet Dialogs { get; private set; }
/// <summary>
/// Turn context.
/// Gets turn context.
/// </summary>
/// <value>
/// The context for the current turn of conversation.
/// </value>
public ITurnContext Context { get; private set; }
/// <summary>
/// Gets the current dialog stack.
/// </summary>
/// <value>
/// The current dialog stack.
/// </value>
public IList<DialogInstance> Stack { get; private set; }
/// <summary>
/// Current active scoped state with (user|conversation|dialog|settings scopes).
/// Gets current active scoped state with (user|conversation|dialog|settings scopes).
/// </summary>
/// <value>
/// Current active scoped state with (user|conversation|dialog|settings scopes).
/// </value>
public DialogContextState State { get; private set; }
/// <summary>
/// Dialog context for child if there is an active child.
/// Gets dialog context for child if there is an active child.
/// </summary>
/// <value>
/// Dialog context for child if there is an active child.
/// </value>
public DialogContext Child
{
get
@ -143,13 +167,21 @@ namespace Microsoft.Bot.Builder.Dialogs
}
/// <summary>
/// Returns a list of all `Dialog.tags` that are currently on the dialog stack.
/// Gets a list of all `Dialog.tags` that are currently on the dialog stack.
/// Any duplicate tags are removed from the returned list and the order of the tag reflects the
/// order of the dialogs on the stack.
/// The returned list will also include any tags applied as "globalTags". These tags are
/// retrieved by calling context.TurnState.get('globalTags')` and will therefore need to be
/// assigned for every turn of conversation using context.TurnState.set('globalTags', ['myTag'])`.
/// </summary>
/// <value>
/// Returns a list of all `Dialog.tags` that are currently on the dialog stack.
/// Any duplicate tags are removed from the returned list and the order of the tag reflects the
/// order of the dialogs on the stack.
/// The returned list will also include any tags applied as "globalTags". These tags are
/// retrieved by calling context.TurnState.get('globalTags')` and will therefore need to be
/// assigned for every turn of conversation using context.TurnState.set('globalTags', ['myTag'])`.
/// </value>
public List<string> ActiveTags
{
get
@ -184,8 +216,11 @@ namespace Microsoft.Bot.Builder.Dialogs
}
/// <summary>
/// The current dialog state for the active dialog.
/// Gets the current dialog state for the active dialog.
/// </summary>
/// <value>
/// The current dialog state for the active dialog.
/// </value>
public Dictionary<string, object> DialogState
{
get
@ -409,9 +444,14 @@ namespace Microsoft.Bot.Builder.Dialogs
/// <summary>
/// Deletes any existing dialog stack thus cancelling all dialogs on the stack.
/// </summary>
/// <param name="eventName">The event.</param>
/// <param name="eventValue">The event value.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The dialog context.</returns>
public async Task<DialogTurnResult> CancelAllDialogsAsync(string eventName = DialogEvents.CancelDialog, object eventValue = null, CancellationToken cancellationToken = default(CancellationToken))
public async Task<DialogTurnResult> CancelAllDialogsAsync(
string eventName = DialogEvents.CancelDialog,
object eventValue = null,
CancellationToken cancellationToken = default(CancellationToken))
{
if (eventValue is CancellationToken)
{

Просмотреть файл

@ -15,16 +15,6 @@ namespace Microsoft.Bot.Builder.Dialogs
{
public class DialogContextState : IDictionary<string, object>
{
private const string PrefixCallBack = "callstackScope('";
private static JsonSerializerSettings expressionCaseSettings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() },
NullValueHandling = NullValueHandling.Ignore,
};
private readonly DialogContext dialogContext;
/// <summary>
/// Common state properties paths.
/// </summary>
@ -40,6 +30,16 @@ namespace Microsoft.Bot.Builder.Dialogs
public const string STEP_OPTIONS_PROPERTY = "dialog.step.options";
private const string PrefixCallBack = "callstackScope('";
private static JsonSerializerSettings expressionCaseSettings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() },
NullValueHandling = NullValueHandling.Ignore,
};
private readonly DialogContext dialogContext;
public DialogContextState(DialogContext dc, IDictionary<string, object> settings, IDictionary<string, object> userState, IDictionary<string, object> conversationState, IDictionary<string, object> turnState)
{
this.dialogContext = dc ?? throw new ArgumentNullException(nameof(dc));
@ -52,24 +52,36 @@ namespace Microsoft.Bot.Builder.Dialogs
/// <summary>
/// Gets or sets settings for the application.
/// </summary>
/// <value>
/// Settings for the application.
/// </value>
[JsonProperty(PropertyName = "settings")]
public IDictionary<string, object> Settings { get; set; }
/// <summary>
/// Gets or sets state associated with the active user in the turn.
/// </summary>
/// <value>
/// State associated with the active user in the turn.
/// </value>
[JsonProperty(PropertyName = "user")]
public IDictionary<string, object> User { get; set; }
/// <summary>
/// Gets or sets state assocaited with the active conversation for the turn.
/// </summary>
/// <value>
/// State assocaited with the active conversation for the turn.
/// </value>
[JsonProperty(PropertyName = "conversation")]
public IDictionary<string, object> Conversation { get; set; }
/// <summary>
/// Gets or sets state associated with the active dialog for the turn.
/// </summary>
/// <value>
/// State associated with the active dialog for the turn.
/// </value>
[JsonProperty(PropertyName = "dialog")]
public IDictionary<string, object> Dialog
{
@ -115,6 +127,9 @@ namespace Microsoft.Bot.Builder.Dialogs
/// <summary>
/// Gets access to the callstack of dialog state.
/// </summary>
/// <value>
/// Access to the callstack of dialog state.
/// </value>
[JsonIgnore]
public IEnumerable<object> CallStack
{
@ -143,6 +158,9 @@ namespace Microsoft.Bot.Builder.Dialogs
/// <summary>
/// Gets or sets state associated with the current turn only (this is non-persisted).
/// </summary>
/// <value>
/// State associated with the current turn only (this is non-persisted).
/// </value>
[JsonProperty(PropertyName = "turn")]
public IDictionary<string, object> Turn { get; set; }

Просмотреть файл

@ -8,18 +8,28 @@ namespace Microsoft.Bot.Builder.Dialogs
public class DialogEvent
{
/// <summary>
/// If `true` the event will be bubbled to the parent `DialogContext` if not handled by the current dialog.
/// Gets or sets a value indicating whether the event will be bubbled to the parent `DialogContext`
/// if not handled by the current dialog.
/// </summary>
/// <value>
/// Whether the event can be bubbled to the parent `DialogContext`.
/// </value>
public bool Bubble { get; set; }
/// <summary>
/// Name of the event being raised.
/// Gets or sets name of the event being raised.
/// </summary>
/// <value>
/// Name of the event being raised.
/// </value>
public string Name { get; set; }
/// <summary>
/// Optional value associated with the event.
/// Gets or sets optional value associated with the event.
/// </summary>
/// <value>
/// Optional value associated with the event.
/// </value>
public object Value { get; set; }
}
}

Просмотреть файл

@ -29,9 +29,13 @@ namespace Microsoft.Bot.Builder.Dialogs
public IDictionary<string, object> State { get; set; }
/// <summary>
/// Gets or sets a stack index. Positive values are indexes within the current DC and negative values are
/// indexes in the parent DC.
/// </summary>
/// <value>
/// Positive values are indexes within the current DC and negative values are indexes in
/// the parent DC.
/// </summary>
/// </value>
public int? StackIndex { get; set; }
}
}

Просмотреть файл

@ -30,8 +30,11 @@ namespace Microsoft.Bot.Builder.Dialogs
}
/// <summary>
/// Root dialog to use to start conversation.
/// Gets or sets root dialog to use to start conversation.
/// </summary>
/// <value>
/// Root dialog to use to start conversation.
/// </value>
public IDialog RootDialog
{
get

Просмотреть файл

@ -125,7 +125,7 @@ namespace Microsoft.Bot.Builder.Dialogs
}
/// <summary>
/// Finds a dialog that was previously added to the set using <see cref="Add(Dialog)"/>.
/// Finds a dialog that was previously added to the set using <see cref="Add(IDialog)"/>.
/// </summary>
/// <param name="dialogId">ID of the dialog/prompt to look up.</param>
/// <returns>The dialog if found, otherwise null.</returns>

Просмотреть файл

@ -38,8 +38,11 @@ namespace Microsoft.Bot.Builder.Dialogs
public object Result { get; set; }
/// <summary>
/// If true, a DialogCommand has ended its parent container and the parent should not perform any further processing.
/// Gets or sets a value indicating whether a DialogCommand has ended its parent container and the parent should not perform any further processing.
/// </summary>
/// <value>
/// Whether a DialogCommand has ended its parent container and the parent should not perform any further processing.
/// </value>
public bool ParentEnded { get; set; }
}
}

Просмотреть файл

@ -12,11 +12,17 @@ namespace Microsoft.Bot.Builder.Dialogs
/// <summary>
/// Gets or sets unique id for the dialog.
/// </summary>
/// <value>
/// Unique id for the dialog.
/// </value>
string Id { get; set; }
/// <summary>
/// Gets tags assigned to the dialog.
/// </summary>
/// <value>
/// Tags assigned to the dialog.
/// </value>
List<string> Tags { get; }
/// <summary>
@ -24,6 +30,9 @@ namespace Microsoft.Bot.Builder.Dialogs
/// </summary>
/// <remarks>Key = property expression to set in this dialog's memory context, Value = property expression of value you want to get from caller's memory context.</remarks>
/// <example>{ "key": "value" } maps to set newDialogState.key = callerDialogState.value.</example>
/// <value>
/// Dictionary of memory bindings which are evaluated in a call to `beginDialog()`.
/// </value>
Dictionary<string, string> InputBindings { get; }
/// <summary>
@ -31,11 +40,17 @@ namespace Microsoft.Bot.Builder.Dialogs
/// </summary>
/// <remarks>This the property which the result of EndDialog() for this dialog will be mapped to in the caller's dialog state.</remarks>
/// <example>$foo will be set to EndDialog(result).</example>
/// <value>
/// Expression in the callers memory to store the result returned via `endDialog()` is called.
/// </value>
string OutputBinding { get; }
/// <summary>
/// Telemetry client.
/// Gets or sets telemetry client.
/// </summary>
/// <value>
/// Telemetry client.
/// </value>
IBotTelemetryClient TelemetryClient { get; set; }
/// <summary>

Просмотреть файл

@ -45,7 +45,7 @@ namespace Microsoft.Bot.Builder.Dialogs
/// ## Prompt Usage
///
/// When used with your bot's <see cref="DialogSet"/> you can simply add a new instance of the prompt as a named
/// dialog using <see cref="DialogSet.Add(Dialog)"/>. You can then start the prompt from a waterfall step using either
/// dialog using <see cref="DialogSet.Add(IDialog)"/>. You can then start the prompt from a waterfall step using either
/// <see cref="DialogContext.BeginDialogAsync(string, object, CancellationToken)"/> or
/// <see cref="DialogContext.PromptAsync(string, PromptOptions, CancellationToken)"/>. The user
/// will be prompted to signin as needed and their access token will be passed as an argument to

Просмотреть файл

@ -19,7 +19,7 @@ namespace Microsoft.Bot.Builder.Dialogs
/// <typeparam name="T">The type of value the prompt returns.</typeparam>
/// <remarks>When the prompt ends, it should return a <typeparamref name="T"/> object that
/// represents the value that was prompted for.
/// Use <see cref="DialogSet.Add(Dialog)"/> or <see cref="ComponentDialog.AddDialog(Dialog)"/>
/// Use <see cref="DialogSet.Add(IDialog)"/> or <see cref="ComponentDialog.AddDialog(IDialog)"/>
/// to add a prompt to a dialog set or component dialog, respectively.
/// Use <see cref="DialogContext.PromptAsync(string, PromptOptions, CancellationToken)"/> or
/// <see cref="DialogContext.BeginDialogAsync(string, object, CancellationToken)"/> to start the prompt.

Просмотреть файл

@ -21,6 +21,9 @@ namespace Microsoft.Bot.Builder.Dialogs
/// <summary>
/// Gets or sets the template to evaluate to create the IMessageActivity.
/// </summary>
/// <value>
/// The template to evaluate to create the IMessageActivity.
/// </value>
public string Template { get; set; }
public async Task<Activity> BindToData(ITurnContext context, object data)

Просмотреть файл

@ -17,15 +17,28 @@ namespace Microsoft.Bot.Builder.Dialogs
/// Initializes a new instance of the <see cref="WaterfallStepContext"/> class.
/// Provides context for a turn of a waterfall dialog. Contains ITurnContext as property 'Context'.
/// </summary>
/// <param name= "parent">The parent of the waterfall dialog.</param>
/// <param name= "parentWaterfall">The parent of the waterfall dialog.</param>
/// <param name= "dc">The dialog's context.</param>
/// <param name= "options">Any options to call the waterfall dialog with.</param>
/// <param name= "values">A dictionary of values which will be persisted across all waterfall steps.</param>
/// <param name= "index">The index of the current waterfall to execute.</param>
/// <param name= "reason">The reason the waterfall step is being executed.</param>
/// <param name= "result">Results returned by a dialog called in the previous waterfall step.</param>
internal WaterfallStepContext(WaterfallDialog parentWaterfall, DialogContext dc, object options, IDictionary<string, object> values, int index, DialogReason reason, object result = null)
: base(dc.Dialogs, turnContext: dc.Context, state: new DialogState(dc.Stack), conversationState: dc.State.Conversation, userState: dc.State.User, settings: dc.State.Settings)
internal WaterfallStepContext(
WaterfallDialog parentWaterfall,
DialogContext dc,
object options,
IDictionary<string, object> values,
int index,
DialogReason reason,
object result = null)
: base(
dc.Dialogs,
turnContext: dc.Context,
state: new DialogState(dc.Stack),
conversationState: dc.State.Conversation,
userState: dc.State.User,
settings: dc.State.Settings)
{
_parentWaterfall = parentWaterfall;
_nextCalled = false;

Просмотреть файл

@ -17,6 +17,161 @@ namespace Microsoft.Bot.Builder.Dialogs
/// </summary>
public class TextMessageActivityGenerator : IMessageActivityGenerator
{
private static int AddJsonAttachment(IMessageActivity activity, string[] lines, int iLine)
{
StringBuilder sb = new StringBuilder();
for (; iLine < lines.Length; iLine++)
{
if (lines[iLine].TrimEnd() == "]")
{
break;
}
sb.AppendLine(lines[iLine]);
}
dynamic obj = JsonConvert.DeserializeObject(sb.ToString());
string contentType = "application/json";
if (obj.type == "AdaptiveCard")
{
contentType = "application/vnd.microsoft.card.adaptive";
}
var attachment = new Attachment(contentType, content: obj);
activity.Attachments.Add(attachment);
return iLine;
}
private static void AddSuggestions(IMessageActivity activity, string line)
{
var value = line.Split('=');
if (value.Length > 1)
{
var suggestions = value[1].Split('|');
activity.SuggestedActions = new SuggestedActions();
activity.SuggestedActions.Actions = suggestions.Select(s =>
{
var text = s.TrimEnd(']').Trim();
return new CardAction(type: ActionTypes.MessageBack, title: text, displayText: text, text: text);
}).ToList();
}
}
private static void AddAttachmentLayout(IMessageActivity activity, string line)
{
var value = line.Split('=');
if (value.Length > 1)
{
activity.AttachmentLayout = value[1].TrimEnd(']').Trim();
}
}
private static int AddGenericCardAtttachment(IMessageActivity activity, string type, string[] lines, int iLine)
{
var attachment = new Attachment(type, content: new JObject());
iLine = BuildGenericCard(attachment.Content, type, lines, iLine);
activity.Attachments.Add(attachment);
return iLine;
}
private static int BuildGenericCard(dynamic card, string type, string[] lines, int iLine)
{
bool lastLine = false;
for (; !lastLine && iLine < lines.Length; iLine++)
{
var line = lines[iLine];
var start = line.IndexOf('=');
if (start > 0)
{
var property = line.Substring(0, start).Trim().ToLower();
var value = line.Substring(start + 1).Trim();
if (value.EndsWith("]"))
{
value = value.TrimEnd(']');
lastLine = true;
}
switch (property.ToLower())
{
case "title":
case "subtitle":
case "text":
case "aspect":
case "value":
case "connectionName":
card[property] = value;
break;
case "image":
case "images":
if (type == HeroCard.ContentType || type == ThumbnailCard.ContentType)
{
// then it's images
if (card["images"] == null)
{
card["images"] = new JArray();
}
var urlObj = new JObject() { { "url", value } };
((JArray)card["images"]).Add(urlObj);
}
else
{
// then it's image
var urlObj = new JObject() { { "url", value } };
card["image"] = urlObj;
}
break;
case "media":
if (card[property] == null)
{
card[property] = new JArray();
}
var mediaObj = new JObject() { { "url", value } };
((JArray)card[property]).Add(mediaObj);
break;
case "buttons":
if (card[property] == null)
{
card[property] = new JArray();
}
foreach (var button in value.Split('|'))
{
var buttonObj = new JObject() { { "title", button.Trim() }, { "type", "imBack" }, { "value", button.Trim() } };
((JArray)card[property]).Add(buttonObj);
}
break;
case "autostart":
case "sharable":
case "autoloop":
card[property] = value.ToLower() == "true";
break;
case "":
break;
default:
System.Diagnostics.Debug.WriteLine(string.Format("Skipping unknown card property {0}", property));
break;
}
if (lastLine)
{
break;
}
}
}
return iLine;
}
// Fixed text constructor
public TextMessageActivityGenerator()
{
@ -57,8 +212,8 @@ namespace Microsoft.Bot.Builder.Dialogs
/// </remarks>
/// <param name="text">text.</param>
/// <param name="data">data to bind to.</param>
/// <param name="languageGenerator">languageGenerator.</param>
/// <param name="turnContext">turnContext.</param>
/// <param name="languageGenerator">languageGenerator.</param>
/// <returns>MessageActivity for it.</returns>
public async Task<IMessageActivity> CreateActivityFromText(string text, object data, ITurnContext turnContext, ILanguageGenerator languageGenerator)
{
@ -270,160 +425,5 @@ namespace Microsoft.Bot.Builder.Dialogs
activity.Attachments.Add(attachment);
}
private static int AddJsonAttachment(IMessageActivity activity, string[] lines, int iLine)
{
StringBuilder sb = new StringBuilder();
for (; iLine < lines.Length; iLine++)
{
if (lines[iLine].TrimEnd() == "]")
{
break;
}
sb.AppendLine(lines[iLine]);
}
dynamic obj = JsonConvert.DeserializeObject(sb.ToString());
string contentType = "application/json";
if (obj.type == "AdaptiveCard")
{
contentType = "application/vnd.microsoft.card.adaptive";
}
var attachment = new Attachment(contentType, content: obj);
activity.Attachments.Add(attachment);
return iLine;
}
private static void AddSuggestions(IMessageActivity activity, string line)
{
var value = line.Split('=');
if (value.Length > 1)
{
var suggestions = value[1].Split('|');
activity.SuggestedActions = new SuggestedActions();
activity.SuggestedActions.Actions = suggestions.Select(s =>
{
var text = s.TrimEnd(']').Trim();
return new CardAction(type: ActionTypes.MessageBack, title: text, displayText: text, text: text);
}).ToList();
}
}
private static void AddAttachmentLayout(IMessageActivity activity, string line)
{
var value = line.Split('=');
if (value.Length > 1)
{
activity.AttachmentLayout = value[1].TrimEnd(']').Trim();
}
}
private static int AddGenericCardAtttachment(IMessageActivity activity, string type, string[] lines, int iLine)
{
var attachment = new Attachment(type, content: new JObject());
iLine = BuildGenericCard(attachment.Content, type, lines, iLine);
activity.Attachments.Add(attachment);
return iLine;
}
private static int BuildGenericCard(dynamic card, string type, string[] lines, int iLine)
{
bool lastLine = false;
for (; !lastLine && iLine < lines.Length; iLine++)
{
var line = lines[iLine];
var start = line.IndexOf('=');
if (start > 0)
{
var property = line.Substring(0, start).Trim().ToLower();
var value = line.Substring(start + 1).Trim();
if (value.EndsWith("]"))
{
value = value.TrimEnd(']');
lastLine = true;
}
switch (property.ToLower())
{
case "title":
case "subtitle":
case "text":
case "aspect":
case "value":
case "connectionName":
card[property] = value;
break;
case "image":
case "images":
if (type == HeroCard.ContentType || type == ThumbnailCard.ContentType)
{
// then it's images
if (card["images"] == null)
{
card["images"] = new JArray();
}
var urlObj = new JObject() { { "url", value } };
((JArray)card["images"]).Add(urlObj);
}
else
{
// then it's image
var urlObj = new JObject() { { "url", value } };
card["image"] = urlObj;
}
break;
case "media":
if (card[property] == null)
{
card[property] = new JArray();
}
var mediaObj = new JObject() { { "url", value } };
((JArray)card[property]).Add(mediaObj);
break;
case "buttons":
if (card[property] == null)
{
card[property] = new JArray();
}
foreach (var button in value.Split('|'))
{
var buttonObj = new JObject() { { "title", button.Trim() }, { "type", "imBack" }, { "value", button.Trim() } };
((JArray)card[property]).Add(buttonObj);
}
break;
case "autostart":
case "sharable":
case "autoloop":
card[property] = value.ToLower() == "true";
break;
case "":
break;
default:
System.Diagnostics.Debug.WriteLine(string.Format("Skipping unknown card property {0}", property));
break;
}
if (lastLine)
{
break;
}
}
}
return iLine;
}
}
}

Просмотреть файл

@ -19,6 +19,9 @@ namespace Microsoft.Bot.Builder.Dialogs
/// <summary>
/// Gets or sets the template to evaluate to create the IMessageActivity.
/// </summary>
/// <value>
/// The template to evaluate to create the IMessageActivity.
/// </value>
public string Template { get; set; }
public async Task<string> BindToData(ITurnContext turnContext, object data)

Просмотреть файл

@ -53,6 +53,11 @@ namespace Microsoft.Bot.Builder.Expressions
/// <returns>Null if value if correct or error string otherwise.</returns>
public delegate string VerifyExpression(object value, Expression expression, int child);
/// <summary>
/// Dictionary of built-in functions.
/// </summary>
private static readonly Dictionary<string, ExpressionEvaluator> _functions = BuildFunctionLookup();
// Validators do static validation of expressions
/// <summary>
@ -229,6 +234,7 @@ namespace Microsoft.Bot.Builder.Expressions
/// </summary>
/// <param name="value">Value to check.</param>
/// <param name="expression">Expression that led to value.</param>
/// <param name="number">No function.</param>
/// <returns>Error or null if valid.</returns>
public static string VerifyNumber(object value, Expression expression, int number)
{
@ -245,6 +251,7 @@ namespace Microsoft.Bot.Builder.Expressions
/// </summary>
/// <param name="value">Value to check.</param>
/// <param name="expression">Expression that led to value.</param>
/// <param name="number">No function.</param>
/// <returns>Error or null if valid.</returns>
public static string VerifyNumericList(object value, Expression expression, int number)
{
@ -272,6 +279,7 @@ namespace Microsoft.Bot.Builder.Expressions
/// </summary>
/// <param name="value">Value to check.</param>
/// <param name="expression">Expression that led to value.</param>
/// <param name="number">No function.</param>
/// <returns>Error or null if valid.</returns>
public static string VerifyContainer(object value, Expression expression, int number)
{
@ -288,6 +296,7 @@ namespace Microsoft.Bot.Builder.Expressions
/// </summary>
/// <param name="value">Value to check.</param>
/// <param name="expression">Expression that led to value.</param>
/// <param name="number">No function.</param>
/// <returns>Error or null if valid.</returns>
public static string VerifyList(object value, Expression expression, int number)
{
@ -322,6 +331,7 @@ namespace Microsoft.Bot.Builder.Expressions
/// </summary>
/// <param name="value">Value to check.</param>
/// <param name="expression">Expression that led to value.</param>
/// <param name="number">No function.</param>
/// <returns>Error or null if valid.</returns>
public static string VerifyInteger(object value, Expression expression, int number)
{
@ -338,6 +348,7 @@ namespace Microsoft.Bot.Builder.Expressions
/// </summary>
/// <param name="value">Value to check.</param>
/// <param name="expression">Expression that led to value.</param>
/// <param name="number">No function.</param>
/// <returns>Error or null if valid.</returns>
public static string VerifyString(object value, Expression expression, int number)
{
@ -354,6 +365,7 @@ namespace Microsoft.Bot.Builder.Expressions
/// </summary>
/// <param name="value">Value to check.</param>
/// <param name="expression">Expression that led to value.</param>
/// <param name="number">No function.</param>
/// <returns>Error or null if valid.</returns>
public static string VerifyNotNull(object value, Expression expression, int number)
{
@ -370,6 +382,7 @@ namespace Microsoft.Bot.Builder.Expressions
/// </summary>
/// <param name="value">Value to check.</param>
/// <param name="expression">Expression that led to value.</param>
/// <param name="number">No function.</param>
/// <returns>Error or null if valid.</returns>
public static string VerifyNumberOrString(object value, Expression expression, int number)
{
@ -386,6 +399,7 @@ namespace Microsoft.Bot.Builder.Expressions
/// </summary>
/// <param name="value">Value to check.</param>
/// <param name="expression">Expression that led to value.</param>
/// <param name="number">No function.</param>
/// <returns>Error or null if valid.</returns>
public static string VerifyBoolean(object value, Expression expression, int number)
{
@ -495,40 +509,6 @@ namespace Microsoft.Bot.Builder.Expressions
return (value, error);
};
/// <summary>
/// walk dialog callstack looking for property.
/// </summary>
/// <param name="expression"></param>
/// <param name="state"></param>
/// <returns></returns>
private static (object value, string error) CallstackScope(Expression expression, object state)
{
// get collection
var (result, error) = AccessProperty(state, "callstack");
if (result != null)
{
var items = (IEnumerable<object>)result;
object property = null;
(property, error) = expression.Children[0].TryEvaluate(state);
if (property != null && error == null)
{
foreach (var item in items)
{
// get property off of item
(result, error) = AccessProperty(item, property.ToString());
// if not null
if (error == null && result != null)
{
// return it
return (result, null);
}
}
}
}
return (null, error);
}
/// <summary>
/// Generate an expression delegate that applies function on the accumulated value after verifying all children.
/// </summary>
@ -691,6 +671,40 @@ namespace Microsoft.Bot.Builder.Expressions
return eval;
}
/// <summary>
/// walk dialog callstack looking for property.
/// </summary>
/// <param name="expression"></param>
/// <param name="state"></param>
/// <returns></returns>
private static (object value, string error) CallstackScope(Expression expression, object state)
{
// get collection
var (result, error) = AccessProperty(state, "callstack");
if (result != null)
{
var items = (IEnumerable<object>)result;
object property = null;
(property, error) = expression.Children[0].TryEvaluate(state);
if (property != null && error == null)
{
foreach (var item in items)
{
// get property off of item
(result, error) = AccessProperty(item, property.ToString());
// if not null
if (error == null && result != null)
{
// return it
return (result, null);
}
}
}
}
return (null, error);
}
private static void ValidateAccessor(Expression expression)
{
var children = expression.Children;
@ -1084,7 +1098,7 @@ namespace Microsoft.Bot.Builder.Expressions
/// <summary>
/// return new object list replace jarray.ToArray&lt;object&gt;().
/// </summary>
/// <param name="jarray"></param>
/// <param name="instance"></param>
/// <returns></returns>
private static IList ResolveListValue(object instance)
{
@ -2009,7 +2023,7 @@ namespace Microsoft.Bot.Builder.Expressions
{
if (products.Count() == 1)
{
result = ResolveValue(products.ElementAt(0)); ;
result = ResolveValue(products.ElementAt(0));
}
else if (products.Count() > 1)
{
@ -3305,10 +3319,5 @@ namespace Microsoft.Bot.Builder.Expressions
lookup.Add("concat", lookup[ExpressionType.Concat]);
return lookup;
}
/// <summary>
/// Dictionary of built-in functions.
/// </summary>
private static readonly Dictionary<string, ExpressionEvaluator> _functions = BuildFunctionLookup();
}
}

Просмотреть файл

@ -10,12 +10,12 @@ namespace Microsoft.Bot.Builder.Expressions
{
public class CommonRegex
{
private static readonly LRUCache<string, Regex> regexCache = new LRUCache<string, Regex>(15);
private static readonly LRUCache<string, Regex> RegexCache = new LRUCache<string, Regex>(15);
public static Regex CreateRegex(string pattern)
{
Regex result;
if (!string.IsNullOrEmpty(pattern) && regexCache.TryGet(pattern, out var regex))
if (!string.IsNullOrEmpty(pattern) && RegexCache.TryGet(pattern, out var regex))
{
result = regex;
}
@ -27,7 +27,7 @@ namespace Microsoft.Bot.Builder.Expressions
}
result = new Regex(pattern, RegexOptions.Compiled);
regexCache.Set(pattern, result);
RegexCache.Set(pattern, result);
}
return result;

Просмотреть файл

@ -259,7 +259,7 @@ namespace Microsoft.Bot.Builder.Expressions
/// Evaluate the expression.
/// </summary>
/// <param name="state">
/// Global state to evaluate accessor expressions against. Can be <see cref="IDictionary{String, Object}"/>,
/// Global state to evaluate accessor expressions against. Can be <see cref="IDictionary{String, Object}"/>,
/// <see cref="IDictionary"/> otherwise reflection is used to access property and then indexer.
/// </param>
/// <returns>Computed value and an error string. If the string is non-null, then there was an evaluation error.</returns>

Просмотреть файл

@ -54,8 +54,11 @@ namespace Microsoft.Bot.Builder.LanguageGeneration
}
/// <summary>
/// Generators.
/// Gets or sets generators.
/// </summary>
/// <value>
/// Generators.
/// </value>
public ConcurrentDictionary<string, ILanguageGenerator> LanguageGenerators { get; set; } = new ConcurrentDictionary<string, ILanguageGenerator>(StringComparer.OrdinalIgnoreCase);
public static ImportResolverDelegate ResourceResolver(ResourceExplorer resourceExplorer) =>

Просмотреть файл

@ -28,8 +28,11 @@ namespace Microsoft.Bot.Builder.LanguageGeneration
public abstract bool TryGetGenerator(ITurnContext context, string locale, out ILanguageGenerator generator);
/// <summary>
/// Language Policy which defines per language fallback policies.
/// Gets or sets language Policy which defines per language fallback policies.
/// </summary>
/// <value>
/// Language Policy which defines per language fallback policies.
/// </value>
public ILanguagePolicy LanguagePolicy { get; set; } = new LanguagePolicy();
public async Task<string> Generate(ITurnContext turnContext, string template, object data)

Просмотреть файл

@ -16,7 +16,7 @@ namespace Microsoft.Bot.Builder.LanguageGeneration
/// Initializes a new instance of the <see cref="ResourceMultiLanguageGenerator"/> class.
/// </summary>
/// <param name="resourceId">foo.lg.</param>
public ResourceMultiLanguageGenerator(string resourceId=null)
public ResourceMultiLanguageGenerator(string resourceId = null)
{
this.ResourceId = resourceId;
}

Просмотреть файл

@ -45,6 +45,9 @@ namespace Microsoft.Bot.Builder.LanguageGeneration
/// <summary>
/// Gets or sets id of the source of this template (used for labeling errors).
/// </summary>
/// <value>
/// Id of the source of this template (used for labeling errors).
/// </value>
public string Id { get; set; } = String.Empty;
/// <summary>

Просмотреть файл

@ -20,13 +20,19 @@ namespace Microsoft.Bot.Builder.TemplateManager
}
/// <summary>
/// Template Renderers.
/// Gets or sets template Renderers.
/// </summary>
/// <value>
/// Template Renderers.
/// </value>
public List<ITemplateRenderer> Renderers { get; set; } = new List<ITemplateRenderer>();
/// <summary>
/// Language fallback policy.
/// Gets or sets language fallback policy.
/// </summary>
/// <value>
/// Language fallback policy.
/// </value>
public List<string> LanguageFallback { get; set; } = new List<string>();
/// <summary>

Просмотреть файл

@ -29,13 +29,19 @@ namespace Microsoft.Bot.Builder.TemplateManager
}
/// <summary>
/// Template Renderers.
/// Gets or sets template Renderers.
/// </summary>
/// <value>
/// Template Renderers.
/// </value>
public List<ITemplateRenderer> Renderers { get { return this.TemplateManager.Renderers; } set { this.TemplateManager.Renderers = value; } }
/// <summary>
/// Language fallback policy.
/// Gets or sets language fallback policy.
/// </summary>
/// <value>
/// Language fallback policy.
/// </value>
public List<string> LanguageFallback { get { return this.TemplateManager.LanguageFallback; } set { this.TemplateManager.LanguageFallback = value; } }
/// <summary>

Просмотреть файл

@ -20,16 +20,16 @@ namespace Microsoft.Bot.Builder
/// </remarks>
public class FileTranscriptLogger : ITranscriptStore
{
private string folder;
private bool unitTestMode;
private HashSet<string> started = new HashSet<string>();
private static JsonSerializerSettings jsonSettings = new JsonSerializerSettings()
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
};
private string folder;
private bool unitTestMode;
private HashSet<string> started = new HashSet<string>();
/// <summary>
/// Initializes a new instance of the <see cref="FileTranscriptLogger"/> class.
/// </summary>

Просмотреть файл

@ -105,7 +105,7 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees.Tests
Rand = new Random(seed);
}
private static readonly string[] comparisons = new string[]
private static readonly string[] Comparisons = new string[]
{
ExpressionType.LessThan,
ExpressionType.LessThanOrEqual,
@ -164,7 +164,7 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees.Tests
{
Expression expression = null;
object value = null;
var type = RandomChoice<string>(comparisons);
var type = RandomChoice<string>(Comparisons);
switch (Rand.Next(2))
{
case 0:
@ -246,7 +246,8 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees.Tests
do
{
choice = Rand.Next(predicates.Count);
} while (used.Contains(choice));
}
while (used.Contains(choice));
expressions.Add(predicates[choice]);
used.Add(choice);
@ -273,7 +274,8 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees.Tests
do
{
choice = Rand.Next(predicates.Count);
} while (used.Contains(choice));
}
while (used.Contains(choice));
expressions.Add(predicates[choice]);
used.Add(choice);
}
@ -299,7 +301,8 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees.Tests
do
{
choice = Rand.Next(predicates.Count);
} while (used.Contains(choice));
}
while (used.Contains(choice));
var predicate = predicates[choice];
if (j == 0)
@ -386,11 +389,13 @@ namespace Microsoft.Bot.Builder.AI.TriggerTrees.Tests
for (var quant = 0; quant < maxBase; ++quant)
{
KeyValuePair<string, Comparison> baseBinding;
// Can only map each expression variable once in a quantifier
do
{
baseBinding = expression.Bindings.ElementAt(Rand.Next(expression.Bindings.Count));
} while (chosen.Contains(baseBinding.Key));
}
while (chosen.Contains(baseBinding.Key));
chosen.Add(baseBinding.Key);
SplitMemory(baseBinding.Key, out var baseName);
var mappings = new List<string>();

Просмотреть файл

@ -425,12 +425,14 @@ namespace Microsoft.Bot.Builder.Azure.Tests
Assert.AreEqual("foo", pagedResult.Items[0].AsMessageActivity().Text);
Assert.AreEqual("new response", pagedResult.Items[1].AsMessageActivity().Text);
Assert.AreEqual("update", pagedResult.Items[2].AsMessageActivity().Text);
// Perform some queries
pagedResult = await TranscriptStore.GetTranscriptActivitiesAsync(conversation.ChannelId, conversation.Conversation.Id, null, DateTimeOffset.MinValue);
Assert.AreEqual(3, pagedResult.Items.Length);
Assert.AreEqual("foo", pagedResult.Items[0].AsMessageActivity().Text);
Assert.AreEqual("new response", pagedResult.Items[1].AsMessageActivity().Text);
Assert.AreEqual("update", pagedResult.Items[2].AsMessageActivity().Text);
// Perform some queries
pagedResult = await TranscriptStore.GetTranscriptActivitiesAsync(conversation.ChannelId, conversation.Conversation.Id, null, DateTimeOffset.MaxValue);
Assert.AreEqual(0, pagedResult.Items.Length);

Просмотреть файл

@ -57,7 +57,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
{
new TextInput() { Prompt = new ActivityTemplate("Hello, what is your name?"), OutputBinding = "user.name" },
new SendActivity("Hello {user.name}, nice to meet you!"),
})});
})
});
await CreateFlow(testDialog)
.Send("hi")
@ -129,7 +130,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Name = "test",
ValueType = "memory"
}
})});
})
});
await CreateFlow(dialog, sendTrace: true)
.Send("hi")
@ -164,7 +166,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Condition = "!dialog.foo && user.name == null",
Actions = new List<IDialog>()
{
new TextInput() {
new TextInput()
{
Prompt = new ActivityTemplate("Hello, what is your name?"),
OutputBinding = "user.name"
},
@ -175,7 +178,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("Hello {user.name}, nice to see you again!")
}
},
})});
})
});
await CreateFlow(testDialog)
.Send("hi")
@ -366,7 +370,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
}
},
new SendActivity("Hello {user.name}, nice to meet you!")
})});
})
});
await CreateFlow(testDialog)
.Send("hi")
@ -389,7 +394,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
{
Actions = new List<IDialog>()
{
new NumberInput() {
new NumberInput()
{
MaxTurnCount = 1,
DefaultValue = "10",
Prompt = new ActivityTemplate("What is your age?"),
@ -817,7 +823,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
}
},
new SendActivity("Hello {user.name}, nice to meet you!")
})});
})
});
await CreateFlow(testDialog)
.Send("hi")
@ -836,7 +843,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
{
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Replace", "(?i)replace" }
}
}
@ -848,7 +856,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
{
Actions = new List<IDialog>()
{
new TextInput() {
new TextInput()
{
Prompt = new ActivityTemplate("Say replace to replace these actions"),
Property = "turn.tempInput"
},
@ -856,15 +865,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new RepeatDialog()
}
},
new OnIntent() {
new OnIntent()
{
Intent = "Replace",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
new SendActivity("I'm going to replace the original actions via EditActions"),
new EditActions() {
new EditActions()
{
ChangeType = ActionChangeType.ReplaceSequence,
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
new SendActivity("New actions..."),
new TextInput() {
new TextInput()
{
Prompt = new ActivityTemplate("What's your name?"),
Property = "turn.tempInput"
}
@ -891,7 +905,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
{
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Insert", "(?i)insert" },
{ "Execute", "(?i)execute" }
}
@ -968,7 +983,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
}
},
new SendActivity("Hello {user.name}, nice to meet you!")
})});
})
});
await CreateFlow(testDialog)
.Send("hi")

Просмотреть файл

@ -120,7 +120,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Actions = new List<IDialog>()
{
// Add item
new TextInput() {
new TextInput()
{
AlwaysPrompt = true,
Prompt = new ActivityTemplate("Please add an item to todos."),
Property = "dialog.todo"
@ -138,7 +139,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity() { Activity = new ActivityTemplate("Your todos: {join(user.todos, ',')}") },
// Remove item
new TextInput() {
new TextInput()
{
AlwaysPrompt = true,
Prompt = new ActivityTemplate("Enter a item to remove."),
Property = "dialog.todo"
@ -147,7 +149,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity() { Activity = new ActivityTemplate("Your todos: {join(user.todos, ',')}") },
// Add item and pop item
new TextInput() {
new TextInput()
{
AlwaysPrompt = true,
Prompt = new ActivityTemplate("Please add an item to todos."),
Property = "dialog.todo"
@ -209,7 +212,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Condition = "user.name == null",
Actions = new List<IDialog>()
{
new TextInput() {
new TextInput()
{
Prompt = new ActivityTemplate("Hello, what is your name?"),
Property = "user.name"
},
@ -350,7 +354,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
},
new OnIntent()
{
Intent="JokeIntent",
Intent = "JokeIntent",
Actions = new List<IDialog>()
{
new SendActivity("Why did the chicken cross the road?"),
@ -360,7 +364,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
},
new OnIntent()
{
Intent="HelloIntent",
Intent = "HelloIntent",
Actions = new List<IDialog>()
{
new SendActivity("Hello {user.name}, nice to meet you!")
@ -420,7 +424,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
},
new OnIntent()
{
Intent= "GreetingIntent",
Intent = "GreetingIntent",
Actions = new List<IDialog>()
{
new SendActivity("Hello {user.name}, nice to meet you!")
@ -586,7 +590,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
}
};
innerDialog.AddDialogs(new[] {
innerDialog.AddDialogs(new[]
{
new AdaptiveDialog("Greeting")
{
Events = new List<IOnEvent>()
@ -1096,7 +1101,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Generator = new TemplateEngineLanguageGenerator(),
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Interruption", "(?i)interrupt" },
{ "Greeting", "(?i)hi" },
{ "Start", "(?i)start" },
@ -1117,7 +1123,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new OnIntent()
{
Intent = "reset",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
new DeleteProperty()
{
Property = "user.name"
@ -1125,10 +1132,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("Sure. I've reset your profile.")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "Start",
Actions = new List<IDialog>() {
new TextInput() {
Actions = new List<IDialog>()
{
new TextInput()
{
Prompt = new ActivityTemplate("What is your name?"),
Property = "user.name",
AllowInterruptions = AllowInterruptions.Always
@ -1136,11 +1146,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("I have {user.name} as your name")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "Interruption",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
// short circuiting Interruption so consultation is terminated.
new SendActivity("In Interruption..."),
// request the active input step to re-process user input.
new SetProperty()
{
@ -1149,9 +1162,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
}
}
},
new OnIntent() {
new OnIntent()
{
Intent = "Greeting",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
new SendActivity("Hi, I'm the test bot!")
}
},
@ -1205,17 +1220,21 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Generator = new TemplateEngineLanguageGenerator(),
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Interruption", "(?i)interrupt" },
{ "Start", "(?i)start" }
}
},
Events = new List<IOnEvent>()
{
new OnIntent() {
new OnIntent()
{
Intent = "Start",
Actions = new List<IDialog>() {
new TextInput() {
Actions = new List<IDialog>()
{
new TextInput()
{
Prompt = new ActivityTemplate("What is your name?"),
Property = "user.name",
AllowInterruptions = AllowInterruptions.Always
@ -1223,11 +1242,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("I have {user.name} as your name")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "Interruption",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
// short circuiting Interruption so consultation is terminated.
new SendActivity("In Interruption..."),
// request the active input step to re-process user input.
new SetProperty()
{
@ -1256,17 +1278,21 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Generator = new TemplateEngineLanguageGenerator(),
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Interruption", "(?i)interrupt" },
{ "Start", "(?i)start" }
}
},
Events = new List<IOnEvent>()
{
new OnIntent() {
new OnIntent()
{
Intent = "Start",
Actions = new List<IDialog>() {
new TextInput() {
Actions = new List<IDialog>()
{
new TextInput()
{
Prompt = new ActivityTemplate("What is your name?"),
Property = "user.name",
AllowInterruptions = AllowInterruptions.Always
@ -1281,11 +1307,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("I have {user.age} as your age")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "Interruption",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
// short circuiting Interruption so consultation is terminated.
new SendActivity("In Interruption..."),
// request the active input step to re-process user input.
new SetProperty()
{
@ -1331,17 +1360,21 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Generator = new TemplateEngineLanguageGenerator(),
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Start", "(?i)start" },
{ "None", "200" }
}
},
Events = new List<IOnEvent>()
{
new OnIntent() {
new OnIntent()
{
Intent = "Start",
Actions = new List<IDialog>() {
new NumberInput() {
Actions = new List<IDialog>()
{
new NumberInput()
{
Prompt = new ActivityTemplate("What is your age?"),
Property = "user.age",
AllowInterruptions = AllowInterruptions.Always,
@ -1355,11 +1388,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("I have {user.age} as your age")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "None",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
// short circuiting Interruption so consultation is terminated.
new SendActivity("In None..."),
// request the active input step to re-process user input.
new SetProperty()
{
@ -1394,16 +1430,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Generator = new TemplateEngineLanguageGenerator(),
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Start", "(?i)start" }
}
},
Events = new List<IOnEvent>()
{
new OnIntent() {
new OnIntent()
{
Intent = "Start",
Actions = new List<IDialog>() {
new NumberInput() {
Actions = new List<IDialog>()
{
new NumberInput()
{
Prompt = new ActivityTemplate("What is your age?"),
Property = "user.age",
AllowInterruptions = AllowInterruptions.NotRecognized,
@ -1417,11 +1457,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("I have {user.age} as your age")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "None",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
// short circuiting Interruption so consultation is terminated.
new SendActivity("In None..."),
// request the active input step to re-process user input.
new SetProperty()
{
@ -1453,16 +1496,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Generator = new TemplateEngineLanguageGenerator(),
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Start", "(?i)start" }
}
},
Events = new List<IOnEvent>()
{
new OnIntent() {
new OnIntent()
{
Intent = "Start",
Actions = new List<IDialog>() {
new NumberInput() {
Actions = new List<IDialog>()
{
new NumberInput()
{
Prompt = new ActivityTemplate("What is your age?"),
Property = "user.age",
AllowInterruptions = AllowInterruptions.Always,
@ -1471,11 +1518,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("I have {user.age} as your age")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "None",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
// short circuiting Interruption so consultation is terminated.
new SendActivity("In None..."),
// request the active input step to re-process user input.
new SetProperty()
{
@ -1510,16 +1560,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Generator = new TemplateEngineLanguageGenerator(),
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Start", "(?i)start" }
}
},
Events = new List<IOnEvent>()
{
new OnIntent() {
new OnIntent()
{
Intent = "Start",
Actions = new List<IDialog>() {
new NumberInput() {
Actions = new List<IDialog>()
{
new NumberInput()
{
Prompt = new ActivityTemplate("What is your age?"),
Property = "user.age",
AllowInterruptions = AllowInterruptions.NotRecognized,
@ -1528,11 +1582,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("I have {user.age} as your age")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "None",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
// short circuiting Interruption so consultation is terminated.
new SendActivity("In None..."),
// request the active input step to re-process user input.
new SetProperty()
{
@ -1566,16 +1623,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Generator = new TemplateEngineLanguageGenerator(),
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Start", "(?i)start" }
}
},
Events = new List<IOnEvent>()
{
new OnIntent() {
new OnIntent()
{
Intent = "Start",
Actions = new List<IDialog>() {
new NumberInput() {
Actions = new List<IDialog>()
{
new NumberInput()
{
Prompt = new ActivityTemplate("What is your age?"),
Property = "user.age",
AllowInterruptions = AllowInterruptions.Never,
@ -1583,11 +1644,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("I have {user.age} as your age")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "None",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
// short circuiting Interruption so consultation is terminated.
new SendActivity("In None..."),
// request the active input step to re-process user input.
new SetProperty()
{
@ -1619,16 +1683,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Generator = new TemplateEngineLanguageGenerator(),
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Start", "(?i)start" }
}
},
Events = new List<IOnEvent>()
{
new OnIntent() {
new OnIntent()
{
Intent = "Start",
Actions = new List<IDialog>() {
new NumberInput() {
Actions = new List<IDialog>()
{
new NumberInput()
{
Prompt = new ActivityTemplate("What is your age?"),
Property = "user.age",
AllowInterruptions = AllowInterruptions.Never,
@ -1637,11 +1705,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("I have {user.age} as your age")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "None",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
// short circuiting Interruption so consultation is terminated.
new SendActivity("In None..."),
// request the active input step to re-process user input.
new SetProperty()
{
@ -1673,16 +1744,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Generator = new TemplateEngineLanguageGenerator(),
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Start", "(?i)start" }
}
},
Events = new List<IOnEvent>()
{
new OnIntent() {
new OnIntent()
{
Intent = "Start",
Actions = new List<IDialog>() {
new NumberInput() {
Actions = new List<IDialog>()
{
new NumberInput()
{
Prompt = new ActivityTemplate("What is your age?"),
Property = "user.age",
AllowInterruptions = AllowInterruptions.Never,
@ -1696,11 +1771,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("I have {user.age} as your age")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "None",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
// short circuiting Interruption so consultation is terminated.
new SendActivity("In None..."),
// request the active input step to re-process user input.
new SetProperty()
{
@ -1733,16 +1811,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Generator = new TemplateEngineLanguageGenerator(),
Recognizer = new RegexRecognizer()
{
Intents = new Dictionary<string, string>() {
Intents = new Dictionary<string, string>()
{
{ "Start", "(?i)start" }
}
},
Events = new List<IOnEvent>()
{
new OnIntent() {
new OnIntent()
{
Intent = "Start",
Actions = new List<IDialog>() {
new NumberInput() {
Actions = new List<IDialog>()
{
new NumberInput()
{
Prompt = new ActivityTemplate("What is your age?"),
Property = "user.age",
AllowInterruptions = AllowInterruptions.Never,
@ -1752,11 +1834,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("I have {user.age} as your age")
}
},
new OnIntent() {
new OnIntent()
{
Intent = "None",
Actions = new List<IDialog>() {
Actions = new List<IDialog>()
{
// short circuiting Interruption so consultation is terminated.
new SendActivity("In None..."),
// request the active input step to re-process user input.
new SetProperty()
{

Просмотреть файл

@ -314,7 +314,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
new SendActivity("{dialog.name}"),
new IfCondition()
{
Condition= "dialog.name == 'testDialog'",
Condition = "dialog.name == 'testDialog'",
Actions = new List<IDialog>()
{
new SendActivity("nested dialogCommand {dialog.name}")
@ -406,6 +406,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
{
InputBindings = new Dictionary<string, string>() { { "$zzz", "dialog.name" } },
DefaultResultProperty = "$zzz",
// test output binding from adaptive dialog
OutputBinding = "dialog.name",
Events = new List<IOnEvent>()
@ -564,14 +565,17 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
await CreateFlow(testDialog)
.SendConversationUpdate()
// d1
.AssertReply("xyz")
.AssertReply("xyz")
.AssertReply("d1")
// d2
.AssertReply("d1")
.AssertReply("xyz")
.AssertReply("bbb")
// d3
.AssertReply("d3")
.AssertReply("zzz")

Просмотреть файл

@ -139,7 +139,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
{
{
"en-us",
new RegexRecognizer() {
new RegexRecognizer()
{
Intents = new Dictionary<string, string>()
{
{ "Greeting", "(?i)howdy" },
@ -149,7 +150,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
},
{
"en-gb",
new RegexRecognizer() {
new RegexRecognizer()
{
Intents = new Dictionary<string, string>()
{
{ "Greeting", "(?i)hiya" },
@ -159,7 +161,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
},
{
"en",
new RegexRecognizer() {
new RegexRecognizer()
{
Intents = new Dictionary<string, string>()
{
{ "Greeting", "(?i)hello" },
@ -169,7 +172,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
},
{
"",
new RegexRecognizer() {
new RegexRecognizer()
{
Intents = new Dictionary<string, string>()
{
{ "Greeting", "(?i)salve" },

Просмотреть файл

@ -51,6 +51,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Tests
Assert.AreEqual("b2", (string)entities.code[1], "should find b2");
tc = CreateContext("red and orange");
// intent assertions
result = await recognizer.RecognizeAsync(tc, CancellationToken.None);
Assert.AreEqual(1, result.Intents.Count, "Should recognize one intent");

Просмотреть файл

@ -53,7 +53,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Composition
{
var defaultOptions = new Options() { };
var overlay= new Options()
var overlay = new Options()
{
LastName = "Smith",
FirstName = "Fred",

Просмотреть файл

@ -26,7 +26,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Composition.Tests
},
Conversation = new ConversationAccount()
{
Id="213123123123"
Id = "213123123123"
}
};
var bc = new TurnContext(b, a);

Просмотреть файл

@ -12,7 +12,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Debugging.Tests
[TestClass]
public sealed class IdentifierTests
{
public static IEnumerable<ulong> Bytes => new[] {
public static IEnumerable<ulong> Bytes => new[]
{
0ul, 0x7Eul, 0x7Ful, 0x80ul, 0x81ul, 0xFFul,
};

Просмотреть файл

@ -187,6 +187,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Declarative.Tests
changeFired.SetResult(true);
}
};
// changed file
File.Delete(testDialogFile);

Просмотреть файл

@ -112,6 +112,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Tests
Assert.AreEqual(3, card.Buttons.Count, "card buttons should be set");
for (int i = 0; i <= 2; i++)
Assert.AreEqual($"Option {i + 1}", card.Buttons[i].Title, "card buttons should be set");
// TODO add all of the other property types
}
@ -138,6 +139,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Tests
Assert.AreEqual(3, card.Buttons.Count, "card buttons should be set");
for (int i = 0; i <= 2; i++)
Assert.AreEqual($"Option {i + 1}", card.Buttons[i].Title, "card buttons should be set");
// TODO add all of the other property types
}
@ -168,6 +170,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Tests
Assert.AreEqual(3, card.Buttons.Count, "card buttons should be set");
for (int i = 0; i <= 2; i++)
Assert.AreEqual($"Option {i + 1}", card.Buttons[i].Title, "card buttons should be set");
// TODO add all of the other property types
}

Просмотреть файл

@ -15,6 +15,10 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
/// Gets or sets the test context which provides
/// information about and functionality for the current test run.
///</summary>
/// <value>
/// The test context which provides
/// information about and functionality for the current test run.
/// </value>
public TestContext TestContext
{
get { return testContextInstance; }
@ -133,6 +137,7 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
Test("lessOrEquals(one)"), // function need two parameters
Test("equals(one)"), // equals must accept two parameters
Test("exists(1, 2)"), // function need one parameter
//Test("if(!exists(one), one, hello)"), // the second and third parameters of if must the same type
Test("not(false, one)"), // function need one parameter
# endregion

Просмотреть файл

@ -15,7 +15,7 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
public static HashSet<string> one = new HashSet<string> { "one" };
public static HashSet<string> oneTwo = new HashSet<string> { "one", "two" };
private static readonly string nullStr = null;
private static readonly string NullStr = null;
private readonly object scope = new Dictionary<string, object>
{
@ -26,8 +26,9 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
{ "cit", "cit" },
{ "y", "y" },
{ "istrue", true },
{ "nullObj", nullStr },
{ "bag", new Dictionary<string, object>
{ "nullObj", NullStr },
{
"bag", new Dictionary<string, object>
{
{ "three", 3.0 },
{ "set", new { four = 4.0 } },
@ -37,7 +38,8 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
}
},
{ "items", new string[] { "zero", "one", "two" } },
{ "nestedItems",
{
"nestedItems",
new[]
{
new { x = 1 },
@ -45,7 +47,8 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
new { x = 3 }
}
},
{ "user",
{
"user",
new
{
lists = new
@ -65,7 +68,8 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
{ "timestampObj", DateTime.Parse("2018-03-15T13:00:00.000Z").ToUniversalTime() },
{ "unixTimestamp", 1521118800 },
{ "xmlStr", "<?xml version='1.0'?> <produce> <item> <name>Gala</name> <type>apple</type> <count>20</count> </item> <item> <name>Honeycrisp</name> <type>apple</type> <count>10</count> </item> </produce>" },
{ "jsonStr", @"{
{
"jsonStr", @"{
'Stores': [
'Lambton Quay',
'Willis Street'
@ -95,7 +99,8 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
}
]
}"},
{ "turn", new
{
"turn", new
{
recognized = new
{
@ -161,7 +166,8 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
}
}
},
{ "dialog",
{
"dialog",
new
{
x=3,
@ -182,7 +188,8 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
subTitle = "Dialog Sub Title"
}
},
{ "callstack", new object[]
{
"callstack", new object[]
{
new
{
@ -460,6 +467,7 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
# endregion
# region Date and time function test
//init dateTime: 2018-03-15T13:00:00Z
Test("addDays(timestamp, 1)", "2018-03-16T13:00:00.000Z"),
Test("addDays(timestamp, 1,'MM-dd-yy')", "03-16-18"),
@ -618,6 +626,7 @@ namespace Microsoft.Bot.Builder.Expressions.Tests
Test("$x", 3),
Test("$y", 2),
Test("$z", 1),
// Test("^x", 3),
// Test("^y", 2),
// Test("^z", 1),

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше