diff --git a/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs b/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs index cb1a801ec204..3d52b6ea45c1 100644 --- a/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs +++ b/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs @@ -21,12 +21,14 @@ var chatCompletionService = kernel.GetRequiredService(); var settings = new OllamaPromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }; -Console.WriteLine("Ask questions or give instructions to the copilot such as:\n" + - "- Change the alarm to 8\n" + - "- What is the current alarm set?\n" + - "- Is the light on?\n" + - "- Turn the light off please.\n" + - "- Set an alarm for 6:00 am.\n"); +Console.WriteLine(""" + Ask questions or give instructions to the copilot such as: + - Change the alarm to 8 + - What is the current alarm set? + - Is the light on? + - Turn the light off please. + - Set an alarm for 6:00 am. + """); Console.Write("> "); diff --git a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs index 6afbcef6ec3a..80e9652519b6 100644 --- a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs +++ b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs @@ -29,6 +29,22 @@ namespace Microsoft.SemanticKernel; [DebuggerDisplay("{DebuggerDisplay,nq}")] internal sealed partial class KernelFunctionFromMethod : KernelFunction { + private static readonly Dictionary> s_jsonStringParsers = new(12) + { + { typeof(bool), s => bool.Parse(s) }, + { typeof(int), s => int.Parse(s) }, + { typeof(uint), s => uint.Parse(s) }, + { typeof(long), s => long.Parse(s) }, + { typeof(ulong), s => ulong.Parse(s) }, + { typeof(float), s => float.Parse(s) }, + { typeof(double), s => double.Parse(s) }, + { typeof(decimal), s => decimal.Parse(s) }, + { typeof(short), s => short.Parse(s) }, + { typeof(ushort), s => ushort.Parse(s) }, + { typeof(byte), s => byte.Parse(s) }, + { typeof(sbyte), s => sbyte.Parse(s) } + }; + /// /// Creates a instance for a method, specified via an instance /// and an optional target object if the method is an instance method. @@ -710,26 +726,34 @@ private static (Func((long)1), //Passed to parameter of type long + ["i"] = JsonSerializer.Deserialize((byte)1), //Passed to parameter of type int + ["d"] = JsonSerializer.Deserialize((float)1.0), //Passed to parameter of type double + ["f"] = JsonSerializer.Deserialize((uint)1.0), //Passed to parameter of type float + ["g"] = JsonSerializer.Deserialize(JsonSerializer.Serialize(new Guid("35626209-b0ab-458c-bfc4-43e6c7bd13dc"))), //Passed to parameter of type string + ["dof"] = JsonSerializer.Deserialize(JsonSerializer.Serialize(DayOfWeek.Thursday)), //Passed to parameter of type int + ["b"] = JsonSerializer.Deserialize(JsonSerializer.Serialize("true")), //Passed to parameter of type bool + }; + + var function = KernelFunctionFactory.CreateFromMethod((long l, int i, double d, float f, string g, int dof, bool b) => + { + Assert.Equal(1, l); + Assert.Equal(1, i); + Assert.Equal(1.0, d); + Assert.Equal("35626209-b0ab-458c-bfc4-43e6c7bd13dc", g); + Assert.Equal(4, dof); + Assert.True(b); + }, + functionName: "Test"); + + await function.InvokeAsync(this._kernel, arguments); + await function.AsAIFunction().InvokeAsync(arguments); + } + + [Fact] + public async Task ItSupportsStringJsonElementArgumentsImplicitConversionAsync() + { + //Arrange + var arguments = new KernelArguments() + { + ["l"] = JsonSerializer.Deserialize(JsonSerializer.Serialize("1")), //Passed to parameter of type long + ["i"] = JsonSerializer.Deserialize(JsonSerializer.Serialize("1")), //Passed to parameter of type int + ["d"] = JsonSerializer.Deserialize(JsonSerializer.Serialize("1.0")), //Passed to parameter of type double + ["f"] = JsonSerializer.Deserialize(JsonSerializer.Serialize("1.0")), //Passed to parameter of type float + ["g"] = JsonSerializer.Deserialize(JsonSerializer.Serialize("35626209-b0ab-458c-bfc4-43e6c7bd13dc")), //Passed to parameter of type Guid + ["dof"] = JsonSerializer.Deserialize(JsonSerializer.Serialize("4")), //Passed to parameter of type int + ["b"] = JsonSerializer.Deserialize(JsonSerializer.Serialize("false")), //Passed to parameter of type bool + }; + + var function = KernelFunctionFactory.CreateFromMethod((long l, int i, double d, float f, Guid g, int dof, bool b) => + { + Assert.Equal(1, l); + Assert.Equal(1, i); + Assert.Equal(1.0, d); + Assert.Equal(new Guid("35626209-b0ab-458c-bfc4-43e6c7bd13dc"), g); + Assert.Equal(4, dof); + Assert.False(b); + }, + functionName: "Test"); + + await function.InvokeAsync(this._kernel, arguments); + await function.AsAIFunction().InvokeAsync(arguments); + } + [Fact] public async Task ItSupportsParametersWithDefaultValuesAsync() {