From 355718d655db096001cd5804a2a6df73375304b7 Mon Sep 17 00:00:00 2001 From: SergeyMenshykh Date: Fri, 4 Apr 2025 13:42:46 +0100 Subject: [PATCH 1/8] expose underlying method from kernel function --- .../Functions/MethodFunctions_Advanced.cs | 57 +++++++++++++++---- .../Functions/KernelFunction.cs | 9 +++ .../Functions/KernelFunctionFromMethod.cs | 16 +++++- .../KernelFunctionFromMethodTests2.cs | 28 +++++++++ 4 files changed, 96 insertions(+), 14 deletions(-) diff --git a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs index 6583e2dee7e2..05dfeeec1d71 100644 --- a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs +++ b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs @@ -2,16 +2,16 @@ using System.ComponentModel; using System.Globalization; +using System.Reflection; +using System.Security.Permissions; using System.Text.Json; using Microsoft.SemanticKernel; namespace Functions; -// This example shows different ways how to define and execute method functions using custom and primitive types. +// These samples show advanced usage of method functions. public class MethodFunctions_Advanced(ITestOutputHelper output) : BaseTest(output) { - #region Method Functions Chaining - /// /// This example executes Function1, which in turn executes Function2. /// @@ -22,7 +22,7 @@ public async Task MethodFunctionsChainingAsync() var kernel = new Kernel(); - var functions = kernel.ImportPluginFromType(); + var functions = kernel.ImportPluginFromType(); var customType = await kernel.InvokeAsync(functions["Function1"]); @@ -31,11 +31,28 @@ public async Task MethodFunctionsChainingAsync() } /// - /// Plugin example with two method functions, where one function is called from another. + /// This example shows how to access the custom attribute the native method wrapped by Kernel Function is annotated with. /// - private sealed class FunctionsChainingPlugin + [Fact] + public async Task AccessNativeMethodAttributes() + { + // Import the plugin containing the method with the InvocationSettingsAttribute custom attribute + var kernel = new Kernel(); + + var functions = kernel.ImportPluginFromType(); + + // Get the kernel function wrapping the method with the InvocationSettingsAttribute + var kernelFunction = functions[nameof(Plugin.FunctionWithInvocationSettingsAttribute)]; + + // Access the custom attribute the underlying method is annotated with + var invocationSettingsAttribute = kernelFunction.UnderlyingMethod!.GetCustomAttribute(); + + Console.WriteLine("Priority: " + invocationSettingsAttribute?.Priority); + } + + private sealed class Plugin { - private const string PluginName = nameof(FunctionsChainingPlugin); + private const string PluginName = nameof(Plugin); [KernelFunction] public async Task Function1Async(Kernel kernel) @@ -59,11 +76,12 @@ public static MyCustomType Function2() Text = "From Function2" }; } - } - - #endregion - #region Custom Type + [KernelFunction, InvocationSettingsAttribute(priority: Priority.High)] + public static void FunctionWithInvocationSettingsAttribute() + { + } + } /// /// In order to use custom types, should be specified, @@ -110,5 +128,20 @@ private sealed class MyCustomTypeConverter : TypeConverter } } - #endregion + [AttributeUsage(AttributeTargets.Method)] + private sealed class InvocationSettingsAttribute : Attribute + { + public InvocationSettingsAttribute(Priority priority = Priority.Normal) + { + this.Priority = priority; + } + + public Priority Priority { get; } + } + + private enum Priority + { + Normal, + High, + } } diff --git a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs index a0a425aca1ec..9a13fb094f49 100644 --- a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs +++ b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs @@ -8,6 +8,7 @@ using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Metrics; using System.Linq; +using System.Reflection; using System.Runtime.CompilerServices; using System.Text.Json; using System.Threading; @@ -98,6 +99,14 @@ public abstract class KernelFunction /// public IReadOnlyDictionary? ExecutionSettings { get; } + /// + /// Gets the underlying that this function might be wrapping. + /// + /// + /// Provides additional metadata on the function and its signature. Implementations not wrapping .NET methods may return null. + /// + public MethodInfo? UnderlyingMethod { get; internal init; } + /// /// Initializes a new instance of the class. /// diff --git a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs index 80e9652519b6..7933c458c025 100644 --- a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs +++ b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs @@ -142,6 +142,7 @@ public static KernelFunction Create( MethodDetails methodDetails = GetMethodDetails(options?.FunctionName, method, target); var result = new KernelFunctionFromMethod( + method, methodDetails.Function, methodDetails.Name, options?.Description ?? methodDetails.Description, @@ -183,6 +184,7 @@ public static KernelFunction Create( MethodDetails methodDetails = GetMethodDetails(options?.FunctionName, method, jsonSerializerOptions, target); var result = new KernelFunctionFromMethod( + method, methodDetails.Function, methodDetails.Name, options?.Description ?? methodDetails.Description, @@ -280,6 +282,7 @@ public static KernelFunctionMetadata CreateMetadata( MethodDetails methodDetails = GetMethodDetails(options?.FunctionName, method, null); var result = new KernelFunctionFromMethod( + method, methodDetails.Function, methodDetails.Name, options?.Description ?? methodDetails.Description, @@ -313,6 +316,7 @@ public static KernelFunctionMetadata CreateMetadata( MethodDetails methodDetails = GetMethodDetails(options?.FunctionName, method, jsonSerializerOptions, target: null); var result = new KernelFunctionFromMethod( + method, methodDetails.Function, methodDetails.Name, options?.Description ?? methodDetails.Description, @@ -388,6 +392,7 @@ public override KernelFunction Clone(string pluginName) if (base.JsonSerializerOptions is not null) { return new KernelFunctionFromMethod( + this.UnderlyingMethod!, this._function, this.Name, pluginName, @@ -403,6 +408,7 @@ public override KernelFunction Clone(string pluginName) KernelFunctionFromMethod Clone() { return new KernelFunctionFromMethod( + this.UnderlyingMethod!, this._function, this.Name, pluginName, @@ -430,17 +436,19 @@ private record struct MethodDetails(string Name, string Description, Implementat [RequiresUnreferencedCode("Uses reflection to handle various aspects of the function creation and invocation, making it incompatible with AOT scenarios.")] [RequiresDynamicCode("Uses reflection to handle various aspects of the function creation and invocation, making it incompatible with AOT scenarios.")] private KernelFunctionFromMethod( + MethodInfo method, ImplementationFunc implementationFunc, string functionName, string description, IReadOnlyList parameters, KernelReturnParameterMetadata returnParameter, ReadOnlyDictionary? additionalMetadata = null) : - this(implementationFunc, functionName, null, description, parameters, returnParameter, additionalMetadata) + this(method, implementationFunc, functionName, null, description, parameters, returnParameter, additionalMetadata) { } private KernelFunctionFromMethod( + MethodInfo method, ImplementationFunc implementationFunc, string functionName, string description, @@ -448,13 +456,14 @@ private KernelFunctionFromMethod( KernelReturnParameterMetadata returnParameter, JsonSerializerOptions jsonSerializerOptions, ReadOnlyDictionary? additionalMetadata = null) : - this(implementationFunc, functionName, null, description, parameters, returnParameter, jsonSerializerOptions, additionalMetadata) + this(method, implementationFunc, functionName, null, description, parameters, returnParameter, jsonSerializerOptions, additionalMetadata) { } [RequiresUnreferencedCode("Uses reflection to handle various aspects of the function creation and invocation, making it incompatible with AOT scenarios.")] [RequiresDynamicCode("Uses reflection to handle various aspects of the function creation and invocation, making it incompatible with AOT scenarios.")] private KernelFunctionFromMethod( + MethodInfo method, ImplementationFunc implementationFunc, string functionName, string? pluginName, @@ -467,9 +476,11 @@ private KernelFunctionFromMethod( Verify.ValidFunctionName(functionName); this._function = implementationFunc; + this.UnderlyingMethod = method; } private KernelFunctionFromMethod( + MethodInfo method, ImplementationFunc implementationFunc, string functionName, string? pluginName, @@ -483,6 +494,7 @@ private KernelFunctionFromMethod( Verify.ValidFunctionName(functionName); this._function = implementationFunc; + this.UnderlyingMethod = method; } [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "This method is AOT save.")] diff --git a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs index 66264fe6bb35..0c09c36e7a10 100644 --- a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs +++ b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs @@ -288,6 +288,24 @@ public void ItMakesProvidedExtensionPropertiesAvailableViaMetadataWhenConstructe Assert.Equal("value1", func.Metadata.AdditionalProperties["key1"]); } + [Fact] + public void ItShouldExposeNativeMethod() + { + // Arrange + var target = new LocalExamplePlugin(); + + var methodInfo = target.GetType().GetMethod(nameof(LocalExamplePlugin.FunctionWithCustomAttribute))!; + + var kernelFunction = KernelFunctionFactory.CreateFromMethod(methodInfo, target); + + // Assert + Assert.NotNull(kernelFunction.UnderlyingMethod); + + Assert.Equal(methodInfo, kernelFunction.UnderlyingMethod); + + Assert.NotNull(kernelFunction.UnderlyingMethod.GetCustomAttribute()); + } + private interface IExampleService; private sealed class ExampleService : IExampleService; @@ -466,6 +484,11 @@ public string WithPrimitives( { return string.Empty; } + + [KernelFunction, CustomAttribute] + public void FunctionWithCustomAttribute() + { + } } private sealed class GenericPlugin @@ -479,4 +502,9 @@ private sealed class GenericPlugin [KernelFunction] public Task GetValue3Async(T input) => Task.FromResult(input); } + + [AttributeUsage(AttributeTargets.Method)] + private sealed class CustomAttribute : Attribute + { + } } From bc85c7b0409d4359561b2eb2c46764ce1aa9d069 Mon Sep 17 00:00:00 2001 From: SergeyMenshykh Date: Fri, 4 Apr 2025 13:57:20 +0100 Subject: [PATCH 2/8] fix warning --- dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs index 05dfeeec1d71..f27ce580b20a 100644 --- a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs +++ b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs @@ -3,7 +3,6 @@ using System.ComponentModel; using System.Globalization; using System.Reflection; -using System.Security.Permissions; using System.Text.Json; using Microsoft.SemanticKernel; From d2aca7e7fc14050f5f7ee34f4e889795c14ddea5 Mon Sep 17 00:00:00 2001 From: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com> Date: Fri, 4 Apr 2025 14:07:22 +0100 Subject: [PATCH 3/8] Update dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs Co-authored-by: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> --- .../src/SemanticKernel.Abstractions/Functions/KernelFunction.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs index 9a13fb094f49..de499f3c6531 100644 --- a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs +++ b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs @@ -105,7 +105,7 @@ public abstract class KernelFunction /// /// Provides additional metadata on the function and its signature. Implementations not wrapping .NET methods may return null. /// - public MethodInfo? UnderlyingMethod { get; internal init; } + public MethodInfo? InnerMethod { get; internal init; } /// /// Initializes a new instance of the class. From 590a132400a1aec888660b7211c15d9f3673d666 Mon Sep 17 00:00:00 2001 From: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com> Date: Fri, 4 Apr 2025 14:07:38 +0100 Subject: [PATCH 4/8] Update dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs Co-authored-by: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> --- dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs index f27ce580b20a..fefae6ee9214 100644 --- a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs +++ b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs @@ -46,7 +46,7 @@ public async Task AccessNativeMethodAttributes() // Access the custom attribute the underlying method is annotated with var invocationSettingsAttribute = kernelFunction.UnderlyingMethod!.GetCustomAttribute(); - Console.WriteLine("Priority: " + invocationSettingsAttribute?.Priority); + Console.WriteLine($"Priority: {invocationSettingsAttribute?.Priority}"); } private sealed class Plugin From 69c41dd4cf33b9156d26db84b4b3b44062247fc5 Mon Sep 17 00:00:00 2001 From: SergeyMenshykh Date: Fri, 4 Apr 2025 14:09:15 +0100 Subject: [PATCH 5/8] address PR comments --- .../samples/Concepts/Functions/MethodFunctions_Advanced.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs index f27ce580b20a..0797a74e684c 100644 --- a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs +++ b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs @@ -8,14 +8,16 @@ namespace Functions; -// These samples show advanced usage of method functions. +/// +/// These samples show advanced usage of method functions. +/// public class MethodFunctions_Advanced(ITestOutputHelper output) : BaseTest(output) { /// /// This example executes Function1, which in turn executes Function2. /// [Fact] - public async Task MethodFunctionsChainingAsync() + public async Task MethodFunctionsChaining() { Console.WriteLine("Running Method Function Chaining example..."); From d5b4f48518fc46770ad17e937686653902c4a32a Mon Sep 17 00:00:00 2001 From: SergeyMenshykh Date: Fri, 4 Apr 2025 14:17:04 +0100 Subject: [PATCH 6/8] address pr review comments --- .../Concepts/Functions/MethodFunctions_Advanced.cs | 2 +- .../Functions/KernelFunctionFromMethod.cs | 8 ++++---- .../Functions/KernelFunctionFromMethodTests2.cs | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs index f85f263e60a6..e63ee235f111 100644 --- a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs +++ b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs @@ -46,7 +46,7 @@ public async Task AccessNativeMethodAttributes() var kernelFunction = functions[nameof(Plugin.FunctionWithInvocationSettingsAttribute)]; // Access the custom attribute the underlying method is annotated with - var invocationSettingsAttribute = kernelFunction.UnderlyingMethod!.GetCustomAttribute(); + var invocationSettingsAttribute = kernelFunction.InnerMethod!.GetCustomAttribute(); Console.WriteLine($"Priority: {invocationSettingsAttribute?.Priority}"); } diff --git a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs index 49991ad39c5a..74ce7e1f6f37 100644 --- a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs +++ b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs @@ -386,7 +386,7 @@ public override KernelFunction Clone(string pluginName) if (base.JsonSerializerOptions is not null) { return new KernelFunctionFromMethod( - this.UnderlyingMethod!, + this.InnerMethod!, this._function, this.Name, pluginName, @@ -402,7 +402,7 @@ public override KernelFunction Clone(string pluginName) KernelFunctionFromMethod Clone() { return new KernelFunctionFromMethod( - this.UnderlyingMethod!, + this.InnerMethod!, this._function, this.Name, pluginName, @@ -470,7 +470,7 @@ private KernelFunctionFromMethod( Verify.ValidFunctionName(functionName); this._function = implementationFunc; - this.UnderlyingMethod = method; + this.InnerMethod = method; } private KernelFunctionFromMethod( @@ -488,7 +488,7 @@ private KernelFunctionFromMethod( Verify.ValidFunctionName(functionName); this._function = implementationFunc; - this.UnderlyingMethod = method; + this.InnerMethod = method; } [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "This method is AOT save.")] diff --git a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs index 0c09c36e7a10..8260272cd835 100644 --- a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs +++ b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs @@ -299,11 +299,11 @@ public void ItShouldExposeNativeMethod() var kernelFunction = KernelFunctionFactory.CreateFromMethod(methodInfo, target); // Assert - Assert.NotNull(kernelFunction.UnderlyingMethod); + Assert.NotNull(kernelFunction.InnerMethod); - Assert.Equal(methodInfo, kernelFunction.UnderlyingMethod); + Assert.Equal(methodInfo, kernelFunction.InnerMethod); - Assert.NotNull(kernelFunction.UnderlyingMethod.GetCustomAttribute()); + Assert.NotNull(kernelFunction.InnerMethod.GetCustomAttribute()); } private interface IExampleService; From b16b4017645b52b369f973b5ee71c395ea908f9d Mon Sep 17 00:00:00 2001 From: SergeyMenshykh Date: Fri, 4 Apr 2025 14:18:59 +0100 Subject: [PATCH 7/8] address pr review comments --- dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs index e63ee235f111..1093c2f82811 100644 --- a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs +++ b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs @@ -32,10 +32,10 @@ public async Task MethodFunctionsChaining() } /// - /// This example shows how to access the custom attribute the native method wrapped by Kernel Function is annotated with. + /// This example shows how to access the custom attribute the inner method wrapped by Kernel Function is annotated with. /// [Fact] - public async Task AccessNativeMethodAttributes() + public async Task AccessInnerMethodAttributes() { // Import the plugin containing the method with the InvocationSettingsAttribute custom attribute var kernel = new Kernel(); From 86b22b6d890fae450465abe8a3189b06d03b2339 Mon Sep 17 00:00:00 2001 From: SergeyMenshykh Date: Fri, 4 Apr 2025 14:30:00 +0100 Subject: [PATCH 8/8] address PR review comments --- .../Concepts/Functions/MethodFunctions_Advanced.cs | 6 +++--- .../Functions/KernelFunction.cs | 3 ++- .../Functions/KernelFunctionFromMethod.cs | 8 ++++---- .../Functions/KernelFunctionFromMethodTests2.cs | 8 ++++---- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs index 1093c2f82811..7bc3f2bc02cf 100644 --- a/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs +++ b/dotnet/samples/Concepts/Functions/MethodFunctions_Advanced.cs @@ -32,10 +32,10 @@ public async Task MethodFunctionsChaining() } /// - /// This example shows how to access the custom attribute the inner method wrapped by Kernel Function is annotated with. + /// This example shows how to access the custom attribute the underlying method wrapped by Kernel Function is annotated with. /// [Fact] - public async Task AccessInnerMethodAttributes() + public async Task AccessUnderlyingMethodAttributes() { // Import the plugin containing the method with the InvocationSettingsAttribute custom attribute var kernel = new Kernel(); @@ -46,7 +46,7 @@ public async Task AccessInnerMethodAttributes() var kernelFunction = functions[nameof(Plugin.FunctionWithInvocationSettingsAttribute)]; // Access the custom attribute the underlying method is annotated with - var invocationSettingsAttribute = kernelFunction.InnerMethod!.GetCustomAttribute(); + var invocationSettingsAttribute = kernelFunction.UnderlyingMethod!.GetCustomAttribute(); Console.WriteLine($"Priority: {invocationSettingsAttribute?.Priority}"); } diff --git a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs index de499f3c6531..a77a0f782340 100644 --- a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs +++ b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs @@ -105,7 +105,8 @@ public abstract class KernelFunction /// /// Provides additional metadata on the function and its signature. Implementations not wrapping .NET methods may return null. /// - public MethodInfo? InnerMethod { get; internal init; } + [Experimental("SKEXP0001")] + public MethodInfo? UnderlyingMethod { get; internal init; } /// /// Initializes a new instance of the class. diff --git a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs index 74ce7e1f6f37..49991ad39c5a 100644 --- a/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs +++ b/dotnet/src/SemanticKernel.Core/Functions/KernelFunctionFromMethod.cs @@ -386,7 +386,7 @@ public override KernelFunction Clone(string pluginName) if (base.JsonSerializerOptions is not null) { return new KernelFunctionFromMethod( - this.InnerMethod!, + this.UnderlyingMethod!, this._function, this.Name, pluginName, @@ -402,7 +402,7 @@ public override KernelFunction Clone(string pluginName) KernelFunctionFromMethod Clone() { return new KernelFunctionFromMethod( - this.InnerMethod!, + this.UnderlyingMethod!, this._function, this.Name, pluginName, @@ -470,7 +470,7 @@ private KernelFunctionFromMethod( Verify.ValidFunctionName(functionName); this._function = implementationFunc; - this.InnerMethod = method; + this.UnderlyingMethod = method; } private KernelFunctionFromMethod( @@ -488,7 +488,7 @@ private KernelFunctionFromMethod( Verify.ValidFunctionName(functionName); this._function = implementationFunc; - this.InnerMethod = method; + this.UnderlyingMethod = method; } [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "This method is AOT save.")] diff --git a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs index 8260272cd835..f2800220d8a1 100644 --- a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs +++ b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests2.cs @@ -289,7 +289,7 @@ public void ItMakesProvidedExtensionPropertiesAvailableViaMetadataWhenConstructe } [Fact] - public void ItShouldExposeNativeMethod() + public void ItShouldExposeUnderlyingMethod() { // Arrange var target = new LocalExamplePlugin(); @@ -299,11 +299,11 @@ public void ItShouldExposeNativeMethod() var kernelFunction = KernelFunctionFactory.CreateFromMethod(methodInfo, target); // Assert - Assert.NotNull(kernelFunction.InnerMethod); + Assert.NotNull(kernelFunction.UnderlyingMethod); - Assert.Equal(methodInfo, kernelFunction.InnerMethod); + Assert.Equal(methodInfo, kernelFunction.UnderlyingMethod); - Assert.NotNull(kernelFunction.InnerMethod.GetCustomAttribute()); + Assert.NotNull(kernelFunction.UnderlyingMethod.GetCustomAttribute()); } private interface IExampleService;