// Copyright (c) Microsoft. All rights reserved. using System.Reflection; using Microsoft.SemanticKernel; namespace Functions; public class MethodFunctions_Yaml(ITestOutputHelper output) : BaseTest(output) { private const string FunctionConfig = """ name: ValidateTaskId description: Validate a task id. input_variables: - name: kernel description: Kernel instance. - name: taskId description: Task identifier. is_required: true output_variable: description: String indicating whether or not the task id is valid. """; /// /// This example create a plugin and uses a separate configuration file for the function metadata. /// /// /// Some reasons you would want to do this: /// 1. It's not possible to modify the existing code to add the KernelFunction attribute. /// 2. You want to keep the function metadata separate from the function implementation. /// [Fact] public async Task CreateFunctionFromMethodWithYamlConfigAsync() { var kernel = new Kernel(); var config = KernelFunctionYaml.ToPromptTemplateConfig(FunctionConfig); var target = new ValidatorPlugin(); MethodInfo method = target.GetType().GetMethod(config.Name!)!; var functions = new List(); var functionName = config.Name; var description = config.Description; var parameters = config.InputVariables; functions.Add(KernelFunctionFactory.CreateFromMethod(method, target, new() { FunctionName = functionName, Description = description, Parameters = parameters.Select(p => new KernelParameterMetadata(p.Name) { Description = p.Description, IsRequired = p.IsRequired }).ToList(), })); var plugin = kernel.ImportPluginFromFunctions("ValidatorPlugin", functions); var function = plugin["ValidateTaskId"]; var result = await kernel.InvokeAsync(function, new() { { "taskId", "1234" } }); Console.WriteLine(result.GetValue()); Console.WriteLine("Function Metadata:"); Console.WriteLine(function.Metadata.Description); Console.WriteLine(function.Metadata.Parameters[0].Description); Console.WriteLine(function.Metadata.Parameters[1].Description); } /// /// Plugin example with no KernelFunction or Description attributes. /// private sealed class ValidatorPlugin { public string ValidateTaskId(Kernel kernel, string taskId) { return taskId.Equals("1234", StringComparison.Ordinal) ? "Valid task id" : "Invalid task id"; } } }