You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
### Motivation and Context
1. Why is this change required? Native functions invoked within semantic
functions are currently limited to being called with at most one
argument for the input variable.
2. What problem does it solve? Calling native functions with mutliple
arguments from semantic functions.
3. What scenario does it contribute to? Template Engine
4. If it fixes an open issue, please link to the issue here.
### Description
Please see the ADR for more context on decisions.
To understand the implementation, I would start with the changes in
CodeTokenizer.cs and CodeBlock.cs.
### Contribution Checklist
<!-- Before submitting this PR, please make sure: -->
- [x] The code builds clean without any errors or warnings
- [x] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [x] All unit tests pass, and I have added new tests where possible
- [x] I didn't break anyone 😄
---------
Co-authored-by: Dmytro Struk <[email protected]>
Co-authored-by: Roger Barreto <[email protected]>
# These are optional elements. Feel free to remove any of them.
3
+
status: proposed
4
+
date: 6/16/2023
5
+
deciders: shawncal, hario90
6
+
consulted: dmytrostruk, matthewbolanos
7
+
informed: lemillermicrosoft
8
+
---
9
+
# Add support for multiple named arguments in template function calls
10
+
11
+
## Context and Problem Statement
12
+
13
+
Native functions now support multiple parameters, populated from context values with the same name. Semantic functions currently only support calling native functions with no more than 1 argument. The purpose of these changes is to add support for calling native functions within semantic functions with multiple named arguments.
14
+
15
+
## Decision Drivers
16
+
17
+
* Parity with Guidance
18
+
* Readability
19
+
* Similarity to languages familiar to SK developers
20
+
* YAML compatibility
21
+
22
+
## Considered Options
23
+
24
+
### Syntax idea 1: Using commas
25
+
26
+
```handlebars
27
+
{{Skill.MyFunction street: "123 Main St", zip: "98123", city:"Seattle", age: 25}}
28
+
```
29
+
30
+
Pros:
31
+
32
+
* Commas could make longer function calls easier to read, especially if spaces before and after the arg separator (a colon in this case) are allowed.
33
+
34
+
Cons:
35
+
36
+
* Guidance doesn't use commas
37
+
* Spaces are already used as delimiters elsewhere so the added complexity of supporting commas isn't necessary
38
+
39
+
### Syntax idea 2: JavaScript/C#-Style delimiter (colon)
40
+
41
+
```handlebars
42
+
43
+
{{MyFunction street:"123 Main St" zip:"98123" city:"Seattle" age: "25"}}
44
+
45
+
```
46
+
47
+
Pros:
48
+
49
+
* Resembles JavaScript Object syntax and C# named argument syntax
50
+
51
+
Cons:
52
+
53
+
* Doesn't align with Guidance syntax which uses equal signs as arg part delimiters
54
+
* Too similar to YAML key/value pairs if we support YAML prompts in the future. It's likely possible to support colons as delimiters but would be better to have a separator that is distinct from normal YAML syntax.
55
+
56
+
### Syntax idea 3: Python/Guidance-Style delimiter
57
+
58
+
```handlebars
59
+
{{MyFunction street="123 Main St" zip="98123" city="Seattle"}}
60
+
```
61
+
62
+
Pros:
63
+
64
+
* Resembles Python's keyword argument syntax
65
+
* Resembles Guidance's named argument syntax
66
+
* Not too similar to YAML key/value pairs if we support YAML prompts in the future.
67
+
68
+
Cons:
69
+
70
+
* Doesn't align with C# syntax
71
+
72
+
### Syntax idea 4: Allow whitespace between arg name/value delimiter
73
+
74
+
```handlebars
75
+
{{MyFunction street = "123 Main St" zip = "98123" city = "Seattle"}}
76
+
```
77
+
78
+
Pros:
79
+
80
+
* Follows the convention followed by many programming languages of whitespace flexibility where spaces, tabs, and newlines within code don't impact a program's functionality
81
+
82
+
Cons:
83
+
84
+
* Promotes code that is harder to read unless commas can be used (see [Using Commas](#syntax-idea-1-using-commas))
85
+
* More complexity to support
86
+
* Doesn't align with Guidance which doesn't support spaces before and after the = sign.
87
+
88
+
## Decision Outcome
89
+
90
+
Chosen options: "Syntax idea 3: Python/Guidance-Style keyword arguments", because it aligns well with Guidance's syntax and is the most compatible with YAML and "Syntax idea 4: Allow whitespace between arg name/value delimiter" for more flexible developer experience.
91
+
92
+
Additional decisions:
93
+
94
+
* Continue supporting up to 1 positional argument for backward compatibility. Currently, the argument passed to a function is assumed to be the `$input` context variable.
95
+
96
+
Example
97
+
98
+
```handlebars
99
+
100
+
{{MyFunction "inputVal" street="123 Main St" zip="98123" city="Seattle"}}
101
+
102
+
```
103
+
104
+
* Allow arg values to be defined as strings or variables ONLY, e.g.
If function expects a value other than a string for an argument, the SDK will use the corresponding TypeConverter to parse the string provided when evaluating the expression.
Console.WriteLine("Azure serviceId, endpoint, apiKey, or deploymentName not found. Skipping example.");
29
+
return;
30
+
}
31
+
32
+
IKernelkernel=Kernel.Builder
33
+
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
34
+
.WithAzureChatCompletionService(
35
+
deploymentName:deploymentName,
36
+
endpoint:endpoint,
37
+
serviceId:serviceId,
38
+
apiKey:apiKey)
39
+
.Build();
40
+
41
+
varvariableName="word2";
42
+
varvariableValue=" Potter";
43
+
varcontext=kernel.CreateNewContext();
44
+
context.Variables[variableName]=variableValue;
45
+
46
+
// Load native skill into the kernel skill collection, sharing its functions with prompt templates
47
+
// Functions loaded here are available as "text.*"
48
+
kernel.ImportSkill(newTextSkill(),"text");
49
+
50
+
// Semantic Function invoking text.Concat native function with named arguments input and input2 where input is a string and input2 is set to a variable from context called word2.
51
+
conststringFunctionDefinition=@"
52
+
Write a haiku about the following: {{text.Concat input='Harry' input2=$word2}}
53
+
";
54
+
55
+
// This allows to see the prompt before it's sent to OpenAI
0 commit comments