From 8cd1aef82af486e596aaeec55e9e240c17a6f5b1 Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:34:49 +0000 Subject: [PATCH 01/12] Support for JsonElement arguments --- .../Plugins/TodoPlugin.cs | 18 +++++ .../Demos/OllamaFunctionCalling/Program.cs | 6 +- .../Functions/KernelFunction.cs | 65 ++++++++++++++++++- .../Functions/KernelFunctionFromMethod.cs | 43 ++++++++++-- .../KernelFunctionFromMethodTests1.cs | 60 +++++++++++++++++ 5 files changed, 184 insertions(+), 8 deletions(-) create mode 100644 dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs diff --git a/dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs b/dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs new file mode 100644 index 000000000000..84221f26c4af --- /dev/null +++ b/dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.ComponentModel; +using System; +using Microsoft.SemanticKernel; + +namespace OllamaFunctionCalling; + +public class TodoPlugin +{ + [KernelFunction, Description("Set the completed state of a todo")] + public void SetCompleted( + [Description("Determines the id of the todo to toggle")] Guid id, + [Description("Determines whether to to complete or to resume the todo")] bool complete = true) + { + //... + } +} diff --git a/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs b/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs index cb1a801ec204..c0530c617b1d 100644 --- a/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs +++ b/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs @@ -15,7 +15,8 @@ builder.Plugins .AddFromType() .AddFromObject(new MyLightPlugin(turnedOn: true)) - .AddFromObject(new MyAlarmPlugin("11")); + .AddFromObject(new MyAlarmPlugin("11")) + .AddFromObject(new TodoPlugin()); var kernel = builder.Build(); var chatCompletionService = kernel.GetRequiredService(); @@ -26,7 +27,8 @@ "- 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"); + "- Set an alarm for 6:00 am.\n" + + "- Complete my Todo item 8e7b175e-2451-4521-8a10-6f296d5a1a4f"); Console.Write("> "); diff --git a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs index cc2d260b48a7..fcae054ab679 100644 --- a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs +++ b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs @@ -10,6 +10,8 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.AI; @@ -556,6 +558,8 @@ public KernelAIFunction(KernelFunction kernelFunction, Kernel? kernel) public override AIFunctionMetadata Metadata { get; } + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "The warning is shown and should be addressed at the function creation site; there is no need to show it again at the function invocation sites.")] + [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "The warning is shown and should be addressed at the function creation site; there is no need to show it again at the function invocation sites.")] protected override async Task InvokeCoreAsync( IEnumerable> arguments, CancellationToken cancellationToken) { @@ -563,9 +567,68 @@ public KernelAIFunction(KernelFunction kernelFunction, Kernel? kernel) // Create the KernelArguments from the supplied arguments. KernelArguments args = []; + + var parsers = new Dictionary>(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) } + }; + foreach (var argument in arguments) { - args[argument.Key] = argument.Value; + if (argument.Value is null) + { + args[argument.Key] = null; + continue; + } + + if (argument.Value is not JsonElement or JsonDocument or JsonNode) + { + args[argument.Key] = argument.Value; + continue; + } + + // Resolve the contract used to marshal the value from JSON -- can throw if not supported or not found. + var parameter = this._kernelFunction.Metadata.Parameters.FirstOrDefault(p => p.Name == argument.Key); + if (parameter?.ParameterType is null) + { + args[argument.Key] = argument.Value; + continue; + } + + Type parameterType = parameter.ParameterType; + JsonTypeInfo typeInfo = (this._kernelFunction.JsonSerializerOptions ?? JsonSerializerOptions.Default).GetTypeInfo(parameterType); + + object? argumentValue = null; + if (argument.Value is JsonElement element && element.ValueKind == JsonValueKind.String) + { + if (parsers.TryGetValue(parameterType, out var parser)) + { + args[argument.Key] = parser(element.GetString()!); + continue; + } + } + + argumentValue = argument.Value switch + { + null => null, // Return as-is if null -- if the parameter is a struct this will be handled by MethodInfo.Invoke + JsonElement jsonElement => JsonSerializer.Deserialize(jsonElement, typeInfo), + JsonDocument doc => JsonSerializer.Deserialize(doc, typeInfo), + JsonNode node => JsonSerializer.Deserialize(node, typeInfo), + _ => argument.Value + }; + + args[argument.Key] = argumentValue; } // Invoke the KernelFunction. diff --git a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs index 6afbcef6ec3a..c19413755780 100644 --- a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs +++ b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs @@ -14,6 +14,7 @@ using System.Runtime.ExceptionServices; using System.Text.Json; using System.Text.Json.Nodes; +using System.Text.Json.Serialization.Metadata; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -690,6 +691,22 @@ private static (Func>(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) } + }; + object? parameterFunc(KernelFunction _, Kernel kernel, KernelArguments arguments, CancellationToken __) { // 1. Use the value of the variable if it exists. @@ -712,15 +729,31 @@ 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 string + ["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 string + ["dof"] = JsonSerializer.Deserialize(JsonSerializer.Serialize("4")), //Passed to parameter of type string + ["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() { From 9eef8688aea0f89df1347e382985994d8a6f7056 Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:47:42 +0000 Subject: [PATCH 02/12] Removing Json conversion from AIFunction adapter and moving to the core kernelmethod impl. --- .../Functions/KernelFunction.cs | 61 +------------------ 1 file changed, 1 insertion(+), 60 deletions(-) diff --git a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs index fcae054ab679..61c512de9d00 100644 --- a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs +++ b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs @@ -567,68 +567,9 @@ public KernelAIFunction(KernelFunction kernelFunction, Kernel? kernel) // Create the KernelArguments from the supplied arguments. KernelArguments args = []; - - var parsers = new Dictionary>(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) } - }; - foreach (var argument in arguments) { - if (argument.Value is null) - { - args[argument.Key] = null; - continue; - } - - if (argument.Value is not JsonElement or JsonDocument or JsonNode) - { - args[argument.Key] = argument.Value; - continue; - } - - // Resolve the contract used to marshal the value from JSON -- can throw if not supported or not found. - var parameter = this._kernelFunction.Metadata.Parameters.FirstOrDefault(p => p.Name == argument.Key); - if (parameter?.ParameterType is null) - { - args[argument.Key] = argument.Value; - continue; - } - - Type parameterType = parameter.ParameterType; - JsonTypeInfo typeInfo = (this._kernelFunction.JsonSerializerOptions ?? JsonSerializerOptions.Default).GetTypeInfo(parameterType); - - object? argumentValue = null; - if (argument.Value is JsonElement element && element.ValueKind == JsonValueKind.String) - { - if (parsers.TryGetValue(parameterType, out var parser)) - { - args[argument.Key] = parser(element.GetString()!); - continue; - } - } - - argumentValue = argument.Value switch - { - null => null, // Return as-is if null -- if the parameter is a struct this will be handled by MethodInfo.Invoke - JsonElement jsonElement => JsonSerializer.Deserialize(jsonElement, typeInfo), - JsonDocument doc => JsonSerializer.Deserialize(doc, typeInfo), - JsonNode node => JsonSerializer.Deserialize(node, typeInfo), - _ => argument.Value - }; - - args[argument.Key] = argumentValue; + args[argument.Key] = argument.Value; } // Invoke the KernelFunction. From dd091a52377cd5ee960c34a8c19dd076626936f4 Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:56:32 +0000 Subject: [PATCH 03/12] Remove unused code --- .../src/SemanticKernel.Abstractions/Functions/KernelFunction.cs | 2 -- .../SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs | 1 - 2 files changed, 3 deletions(-) diff --git a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs index 61c512de9d00..0e41bbc9408e 100644 --- a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs +++ b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs @@ -10,8 +10,6 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.AI; diff --git a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs index c19413755780..8e8f5ed4d658 100644 --- a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs +++ b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs @@ -14,7 +14,6 @@ using System.Runtime.ExceptionServices; using System.Text.Json; using System.Text.Json.Nodes; -using System.Text.Json.Serialization.Metadata; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; From 5da2f358202ea1bba724968f89b821e2a126bdf3 Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:03:58 +0000 Subject: [PATCH 04/12] Fix warnings, remove unecessary annotation and simplify Demo instruction message --- .../Demos/OllamaFunctionCalling/Program.cs | 16 +++++++++------- .../Functions/KernelFunction.cs | 2 -- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs b/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs index c0530c617b1d..115ae7f05c7d 100644 --- a/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs +++ b/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs @@ -22,13 +22,15 @@ 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" + - "- Complete my Todo item 8e7b175e-2451-4521-8a10-6f296d5a1a4f"); +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. + - Complete my Todo item 8e7b175e-2451-4521-8a10-6f296d5a1a4f + """); Console.Write("> "); diff --git a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs index 0e41bbc9408e..cc2d260b48a7 100644 --- a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs +++ b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs @@ -556,8 +556,6 @@ public KernelAIFunction(KernelFunction kernelFunction, Kernel? kernel) public override AIFunctionMetadata Metadata { get; } - [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "The warning is shown and should be addressed at the function creation site; there is no need to show it again at the function invocation sites.")] - [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "The warning is shown and should be addressed at the function creation site; there is no need to show it again at the function invocation sites.")] protected override async Task InvokeCoreAsync( IEnumerable> arguments, CancellationToken cancellationToken) { From 540c8332a9d19acea175b1354bfd59a3c92fec21 Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:13:19 +0000 Subject: [PATCH 05/12] Simplify if logic and nesting --- .../Functions/KernelFunctionFromMethod.cs | 46 ++++++++----------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs index 8e8f5ed4d658..b617c409fe0a 100644 --- a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs +++ b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs @@ -726,40 +726,32 @@ private static (Func Date: Thu, 21 Nov 2024 17:21:07 +0000 Subject: [PATCH 06/12] Fix warning/ordering --- .../samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs b/dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs index 84221f26c4af..b326aa6d25d6 100644 --- a/dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs +++ b/dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. -using System.ComponentModel; using System; +using System.ComponentModel; using Microsoft.SemanticKernel; namespace OllamaFunctionCalling; From 5bf25cd246aa56f7a269ecbebcfda626040c6f66 Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:36:20 +0000 Subject: [PATCH 07/12] Remove SYSLIB1222 warning --- .../Connectors.Onnx.UnitTests/Connectors.Onnx.UnitTests.csproj | 2 +- dotnet/src/Connectors/Connectors.Onnx/Connectors.Onnx.csproj | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dotnet/src/Connectors/Connectors.Onnx.UnitTests/Connectors.Onnx.UnitTests.csproj b/dotnet/src/Connectors/Connectors.Onnx.UnitTests/Connectors.Onnx.UnitTests.csproj index 6333d7dd4322..4c4f18c8d93d 100644 --- a/dotnet/src/Connectors/Connectors.Onnx.UnitTests/Connectors.Onnx.UnitTests.csproj +++ b/dotnet/src/Connectors/Connectors.Onnx.UnitTests/Connectors.Onnx.UnitTests.csproj @@ -7,7 +7,7 @@ true enable false - $(NoWarn);SKEXP0001;SKEXP0070;CS1591;IDE1006;RCS1261;CA1031;CA1308;CA1861;CA2007;CA2234;VSTHRD111 + $(NoWarn);SYSLIB1222;SKEXP0001;SKEXP0070;CS1591;IDE1006;RCS1261;CA1031;CA1308;CA1861;CA2007;CA2234;VSTHRD111 diff --git a/dotnet/src/Connectors/Connectors.Onnx/Connectors.Onnx.csproj b/dotnet/src/Connectors/Connectors.Onnx/Connectors.Onnx.csproj index df49c6da0bfb..36e50fa0c9b1 100644 --- a/dotnet/src/Connectors/Connectors.Onnx/Connectors.Onnx.csproj +++ b/dotnet/src/Connectors/Connectors.Onnx/Connectors.Onnx.csproj @@ -6,6 +6,7 @@ $(AssemblyName) net8.0;netstandard2.0 alpha + $(NoWarn);SYSLIB1222 true From c167a347f3d856a27d43f6c4e0692b730b0e35b8 Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:38:39 +0000 Subject: [PATCH 08/12] Remove TodoPlugin --- .../Plugins/TodoPlugin.cs | 18 ------------------ .../Demos/OllamaFunctionCalling/Program.cs | 4 +--- 2 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs diff --git a/dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs b/dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs deleted file mode 100644 index b326aa6d25d6..000000000000 --- a/dotnet/samples/Demos/OllamaFunctionCalling/Plugins/TodoPlugin.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. - -using System; -using System.ComponentModel; -using Microsoft.SemanticKernel; - -namespace OllamaFunctionCalling; - -public class TodoPlugin -{ - [KernelFunction, Description("Set the completed state of a todo")] - public void SetCompleted( - [Description("Determines the id of the todo to toggle")] Guid id, - [Description("Determines whether to to complete or to resume the todo")] bool complete = true) - { - //... - } -} diff --git a/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs b/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs index 115ae7f05c7d..3d52b6ea45c1 100644 --- a/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs +++ b/dotnet/samples/Demos/OllamaFunctionCalling/Program.cs @@ -15,8 +15,7 @@ builder.Plugins .AddFromType() .AddFromObject(new MyLightPlugin(turnedOn: true)) - .AddFromObject(new MyAlarmPlugin("11")) - .AddFromObject(new TodoPlugin()); + .AddFromObject(new MyAlarmPlugin("11")); var kernel = builder.Build(); var chatCompletionService = kernel.GetRequiredService(); @@ -29,7 +28,6 @@ - Is the light on? - Turn the light off please. - Set an alarm for 6:00 am. - - Complete my Todo item 8e7b175e-2451-4521-8a10-6f296d5a1a4f """); Console.Write("> "); From 2aa272dbef2c0d638fa113c667a471064647f62a Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:41:22 +0000 Subject: [PATCH 09/12] Update dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> --- .../Functions/KernelFunctionFromMethodTests1.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs index 73524ccf8446..b21b05291ed7 100644 --- a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs +++ b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs @@ -894,7 +894,7 @@ public async Task ItSupportsJsonElementArgumentsImplicitConversionAsync() ["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 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 }; From 8d5db3f57af8a1fffbc5deeb2716d59fe3578bb9 Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:41:46 +0000 Subject: [PATCH 10/12] Update dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> --- .../Functions/KernelFunctionFromMethodTests1.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs index b21b05291ed7..45958e37031f 100644 --- a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs +++ b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs @@ -923,8 +923,8 @@ public async Task ItSupportsStringJsonElementArgumentsImplicitConversionAsync() ["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 string - ["dof"] = JsonSerializer.Deserialize(JsonSerializer.Serialize("4")), //Passed to parameter of type string + ["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 }; From b7c530a5fc9b8b7c4a0bb7354c47452be5fe07d4 Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Date: Fri, 22 Nov 2024 10:38:04 +0000 Subject: [PATCH 11/12] Revert "Remove SYSLIB1222 warning" This reverts commit 5bf25cd246aa56f7a269ecbebcfda626040c6f66. --- .../Connectors.Onnx.UnitTests/Connectors.Onnx.UnitTests.csproj | 2 +- dotnet/src/Connectors/Connectors.Onnx/Connectors.Onnx.csproj | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dotnet/src/Connectors/Connectors.Onnx.UnitTests/Connectors.Onnx.UnitTests.csproj b/dotnet/src/Connectors/Connectors.Onnx.UnitTests/Connectors.Onnx.UnitTests.csproj index 4c4f18c8d93d..6333d7dd4322 100644 --- a/dotnet/src/Connectors/Connectors.Onnx.UnitTests/Connectors.Onnx.UnitTests.csproj +++ b/dotnet/src/Connectors/Connectors.Onnx.UnitTests/Connectors.Onnx.UnitTests.csproj @@ -7,7 +7,7 @@ true enable false - $(NoWarn);SYSLIB1222;SKEXP0001;SKEXP0070;CS1591;IDE1006;RCS1261;CA1031;CA1308;CA1861;CA2007;CA2234;VSTHRD111 + $(NoWarn);SKEXP0001;SKEXP0070;CS1591;IDE1006;RCS1261;CA1031;CA1308;CA1861;CA2007;CA2234;VSTHRD111 diff --git a/dotnet/src/Connectors/Connectors.Onnx/Connectors.Onnx.csproj b/dotnet/src/Connectors/Connectors.Onnx/Connectors.Onnx.csproj index 36e50fa0c9b1..df49c6da0bfb 100644 --- a/dotnet/src/Connectors/Connectors.Onnx/Connectors.Onnx.csproj +++ b/dotnet/src/Connectors/Connectors.Onnx/Connectors.Onnx.csproj @@ -6,7 +6,6 @@ $(AssemblyName) net8.0;netstandard2.0 alpha - $(NoWarn);SYSLIB1222 true From a8c7c7aead2c4f09f46676b220879c75775eb461 Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:50:42 +0000 Subject: [PATCH 12/12] Address feedback --- .../Functions/KernelFunctionFromMethod.cs | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs index b617c409fe0a..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. @@ -690,22 +706,6 @@ private static (Func>(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) } - }; - object? parameterFunc(KernelFunction _, Kernel kernel, KernelArguments arguments, CancellationToken __) { // 1. Use the value of the variable if it exists. @@ -744,7 +744,7 @@ private static (Func