Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ public object ConstructScope(string inputTemplateName, List<object> args)
}

var parameters = TemplateMap[templateName].Parameters;
var currentScope = _evaluationTargetStack.Count > 0 ? CurrentTarget().Scope : new CustomizedMemory(null);
var currentScope = CurrentTarget().Scope;

if (args.Count == 0)
{
Expand Down
37 changes: 28 additions & 9 deletions libraries/Microsoft.Bot.Builder.LanguageGeneration/Templates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,34 @@ private Templates InjectToExpressionFunction()
if (curTemplates.Any(u => u.Name == templateName))
{
var newGlobalName = $"{curTemplates.Namespace}.{templateName}";
Expression.Functions.Add(newGlobalName, new ExpressionEvaluator(newGlobalName, FunctionUtils.Apply(GlobalTemplateFunction(templateName)), ReturnType.Object));
Expression.Functions.Add(newGlobalName, new ExpressionEvaluator(
newGlobalName,
(expression, state, options) =>
{
object result = null;
var evaluator = new Evaluator(AllTemplates.ToList(), ExpressionParser, LgOptions);
var (args, error) = FunctionUtils.EvaluateChildren(expression, state, options);
if (error == null)
{
var parameters = evaluator.TemplateMap[templateName].Parameters;
var newScope = parameters.Zip(args, (k, v) => new { k, v })
.ToDictionary(x => x.k, x => x.v);
var scope = new CustomizedMemory(state, new SimpleObjectMemory(newScope));
try
{
result = evaluator.EvaluateTemplate(templateName, scope);
}
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception err)
#pragma warning restore CA1031 // Do not catch general exception types
{
error = err.Message;
}
}

return (result, error);
},
ReturnType.Object));
}
}
}
Expand Down Expand Up @@ -622,13 +649,5 @@ private IList<string> GetGlobalFunctionTable(IList<string> options)

return result;
}

private Func<IReadOnlyList<object>, object> GlobalTemplateFunction(string templateName)
=> (IReadOnlyList<object> args) =>
{
var evaluator = new Evaluator(AllTemplates.ToList(), ExpressionParser, LgOptions);
var newScope = evaluator.ConstructScope(templateName, args.ToList());
return evaluator.EvaluateTemplate(templateName, newScope);
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@
"property": "user.message",
"value": "=foo.GetMessage()"
},
{
"$kind": "Microsoft.SetProperty",
"property": "user.name",
"value": "jonathan"
},
{
"$kind": "Microsoft.SetProperty",
"property": "user.date",
"value": "2003-03-20"
},

{
"$kind": "Microsoft.SetProperty",
"property": "user.tasks",
Expand All @@ -28,8 +39,19 @@
{
"$kind": "Microsoft.SendActivity",
"activity": "${user.message}"
},
{
"$kind": "Microsoft.SendActivity",
"activity": "${foo.WelcomeUser()}"
},
{
"$kind": "Microsoft.SendActivity",
"activity": "${foo.UserDataConcat(user.date)}"
},
{
"$kind": "Microsoft.SendActivity",
"activity": "${foo.ShowTasks(foo.GetList(user.tasks))}"
}

]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,9 @@ await CreateFlow(async (turnContext, cancellationToken) =>
.Send("hello")
.AssertReply("[{\"Id\":0,\"Topic\":\"car\"},{\"Id\":1,\"Topic\":\"washing\"},{\"Id\":2,\"Topic\":\"food\"},{\"Id\":3,\"Topic\":\"laundry\"}]")
.AssertReply("This is an injected message")
.AssertReply("Hi Jonathan")
.AssertReply("Jonathan : 2003-03-20")
.AssertReply("Jonathan, your tasks: car, washing, food and laundry")
.StartTestAsync();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
> !# @strict = false
> !# @namespace = foo
> !# @Exports = GetList, Convert, GetProperty, GetMessage
> !# @Exports = GetList, Convert, GetProperty, GetMessage, UserDataConcat, WelcomeUser, ShowTasks


# Convert(index, value)
Expand All @@ -13,4 +13,15 @@
-user.tasks

#GetMessage
- This is an injected message
- This is an injected message

> Use both global and local memory
#UserDataConcat(date)
- ${sentenceCase(user.name)} : ${date}

> Use global memory
#WelcomeUser
- Hi ${sentenceCase(user.name)}

# ShowTasks(tasks)
- ${sentenceCase(user.name)}, your tasks: ${join(foreach(tasks, task, task.value), ', ', ' and ')}
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
> !# @strict = false
> !# @Namespace = foo
> !# @Exports = bar, cool
> !# @Namespace = general
> !# @Exports = sumAll, cool, greeting, addTwoNum, yolo

[import](common.lg)

#bar()
#sumAll()
- ${add(1,2)}

#cool(a)
- ${add(1,a)}
- ${add(1,a)}

#greeting
- hi ${name}

#addTwoNum(a,b)
- ${a + b}

# yolo(a, b)
- ${name} have ${a + b} cookies!
Original file line number Diff line number Diff line change
Expand Up @@ -1481,12 +1481,33 @@ public void TestCustomFunction2()
public void TestInjectLG()
{
var templates = Templates.ParseFile(GetExampleFilePath("./InjectionTest/inject.lg"));

var (evaled, error) = Expression.Parse("foo.bar()").TryEvaluate(null);


var (evaled, error) = Expression.Parse("general.greeting()").TryEvaluate(new { name = "Alice" });
Assert.Equal("hi Alice", evaled.ToString());

var memory1 = new StackedMemory();
memory1.Push(new SimpleObjectMemory(new { name = "Alice" }));
memory1.Push(new CustomizedMemory(new { name = "Bob" }));
(evaled, error) = Expression.Parse("general.greeting()").TryEvaluate(memory1);
Assert.Equal("hi Bob", evaled.ToString());

(evaled, error) = Expression.Parse("general.yolo(8, 7)").TryEvaluate(new { name = "Alice" });
Assert.Equal("Alice have 15 cookies!", evaled.ToString());

var memory2 = new StackedMemory();
memory2.Push(new SimpleObjectMemory(new { name = "Alice" }));
memory2.Push(new CustomizedMemory(new { name = "Bob" }));
(evaled, error) = Expression.Parse("general.yolo(12, 12)").TryEvaluate(memory2);
Assert.Equal("Bob have 24 cookies!", evaled.ToString());

(evaled, error) = Expression.Parse("general.addTwoNum(5,6)").TryEvaluate(new { a = 3, b = 1 });
Assert.Equal("11", evaled.ToString());

(evaled, error) = Expression.Parse("general.sumAll()").TryEvaluate(null);

Assert.Equal("3", evaled.ToString());

(evaled, error) = Expression.Parse("foo.cool(2)").TryEvaluate(null);
(evaled, error) = Expression.Parse("general.cool(2)").TryEvaluate(null);
Assert.Equal("3", evaled.ToString());

(evaled, error) = Expression.Parse("common.looking()").TryEvaluate(null);
Expand Down