chore: import upstream snapshot with attribution
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:21:23 +08:00
commit b957a53def
5423 changed files with 863745 additions and 0 deletions
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<RootNamespace>SemanticKernel.AotCompatibility</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
<NoWarn>VSTHRD111,CA2007;IDE1006,SKEXP0120</NoWarn>
<UserSecretsId>5ee045b0-aea3-4f08-8d31-32d1a6f8fed0</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Connectors\Connectors.Onnx\Connectors.Onnx.csproj" />
<ProjectReference Include="..\..\..\src\SemanticKernel.Abstractions\SemanticKernel.Abstractions.csproj" />
<ProjectReference Include="..\..\..\src\SemanticKernel.Core\SemanticKernel.Core.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
using SemanticKernel.AotCompatibility.Plugins;
namespace SemanticKernel.AotCompatibility.JsonSerializerContexts;
[JsonSerializable(typeof(Location))]
internal sealed partial class LocationJsonSerializerContext : JsonSerializerContext
{
}
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json.Serialization;
using SemanticKernel.AotCompatibility.Plugins;
namespace SemanticKernel.AotCompatibility.JsonSerializerContexts;
[JsonSerializable(typeof(Weather))]
internal sealed partial class WeatherJsonSerializerContext : JsonSerializerContext
{
}
@@ -0,0 +1,47 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using Microsoft.SemanticKernel;
using SemanticKernel.AotCompatibility.JsonSerializerContexts;
using SemanticKernel.AotCompatibility.Plugins;
namespace SemanticKernel.AotCompatibility;
/// <summary>
/// This class contains samples of how to create and invoke kernel functions in AOT applications.
/// </summary>
internal static class KernelFunctionSamples
{
/// <summary>
/// Creates a kernel function from a lambda and invokes it.
/// </summary>
/// <remarks>
/// Other overloads of KernelFunctionFactory.CreateFromMethod can also be used to create functions,
/// as well as the Kernel.CreateFunctionFromMethod extension methods.
/// </remarks>
public static async Task CreateFunctionFromLambda(IConfigurationRoot _)
{
Kernel kernel = new();
// Create JsonSerializerOptions with custom JsonSerializerContexts for the Location and Weather types that are used in the lambda below.
// This is necessary for JsonSerializer to infer the type information for these types in AOT applications.
JsonSerializerOptions options = new();
options.TypeInfoResolverChain.Add(WeatherJsonSerializerContext.Default);
options.TypeInfoResolverChain.Add(LocationJsonSerializerContext.Default);
// Create a kernel function.
KernelFunction function = KernelFunctionFactory.CreateFromMethod(
method: (Location location) => location.City == "Boston" ? new Weather { Temperature = 61, Condition = "rainy" } : throw new NotImplementedException(),
jsonSerializerOptions: options);
// Invoke the function
KernelArguments arguments = new() { ["location"] = new Location("USA", "Boston") };
FunctionResult functionResult = await function.InvokeAsync(kernel, arguments);
// Display the result
Weather weather = functionResult.GetValue<Weather>()!;
Console.WriteLine($"Temperature: {weather.Temperature}, Condition: {weather.Condition}");
}
}
@@ -0,0 +1,109 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using Microsoft.SemanticKernel;
using SemanticKernel.AotCompatibility.JsonSerializerContexts;
using SemanticKernel.AotCompatibility.Plugins;
namespace SemanticKernel.AotCompatibility;
/// <summary>
/// This class contains samples of how to create, import and add kernel plugins and invoke their functions in AOT applications.
/// </summary>
internal static class KernelPluginSamples
{
/// <summary>
/// Creates a kernel plugin from a type and invokes its function.
/// </summary>
/// <remarks>
/// The KernelPluginFactory class provides other methods such as CreateFromObject and CreateFromFunctions,
/// which can be used to create a plugin from a class instance or a list of functions.
/// Additionally, the Kernel.CreatePluginFrom* extension methods are available for similar purposes.
/// </remarks>
public static async Task CreatePluginFromType(IConfigurationRoot _)
{
Kernel kernel = new();
// Create JsonSerializerOptions with custom JsonSerializerContexts for the Location and Weather types that are used by the plugin below.
// This is necessary for JsonSerializer to infer the type information for these types in AOT applications.
JsonSerializerOptions options = new();
options.TypeInfoResolverChain.Add(WeatherJsonSerializerContext.Default);
options.TypeInfoResolverChain.Add(LocationJsonSerializerContext.Default);
// Create a kernel plugin
KernelPlugin plugin = KernelPluginFactory.CreateFromType<WeatherPlugin>(options, "weather_utils");
// Invoke the function
KernelFunction function = plugin["GetCurrentWeather"];
KernelArguments arguments = new() { ["location"] = new Location("USA", "Boston") };
FunctionResult functionResult = await function.InvokeAsync(kernel, arguments);
// Display the result
Weather weather = functionResult.GetValue<Weather>()!;
Console.WriteLine($"Temperature: {weather.Temperature}, Condition: {weather.Condition}");
}
/// <summary>
/// Imports a kernel plugin into the kernel's plugin collection from a type and invokes its function.
/// </summary>
/// <remarks>
/// The kernel provides extension methods like ImportFromObject, ImportFromFunctions and ImportPluginFromPromptDirectory,
/// allowing the import of a plugin from a class instance, a collection of functions or a prompt directory.
/// </remarks>
public static async Task ImportPluginFromType(IConfigurationRoot _)
{
Kernel kernel = new();
// Create JsonSerializerOptions with custom JsonSerializerContexts for the Location and Weather types that are used by the plugin below.
// This is necessary for JsonSerializer to infer the type information for these types in AOT applications.
JsonSerializerOptions options = new();
options.TypeInfoResolverChain.Add(WeatherJsonSerializerContext.Default);
options.TypeInfoResolverChain.Add(LocationJsonSerializerContext.Default);
// Create a kernel plugin
KernelPlugin plugin = kernel.ImportPluginFromType<WeatherPlugin>(options, "weather_utils");
// Invoke the function
KernelFunction function = kernel.Plugins["weather_utils"]["GetCurrentWeather"];
KernelArguments arguments = new() { ["location"] = new Location("USA", "Boston") };
FunctionResult functionResult = await function.InvokeAsync(kernel, arguments);
// Display the result
Weather weather = functionResult.GetValue<Weather>()!;
Console.WriteLine($"Temperature: {weather.Temperature}, Condition: {weather.Condition}");
}
/// <summary>
/// Adds a kernel plugin into the kernel's plugin collection from a type and invokes its function.
/// </summary>
/// <remarks>
/// Other extension methods like AddFromObject, AddFromFunctions
/// can be used to create a plugin and add it to the kernel's plugins collection.
/// </remarks>
public static async Task AddPluginFromType(IConfigurationRoot _)
{
Kernel kernel = new();
// Create JsonSerializerOptions with custom JsonSerializerContexts for the Location and Weather types that are used by the plugin below.
// This is necessary for JsonSerializer to infer the type information for these types in AOT applications.
JsonSerializerOptions options = new();
options.TypeInfoResolverChain.Add(WeatherJsonSerializerContext.Default);
options.TypeInfoResolverChain.Add(LocationJsonSerializerContext.Default);
// Create a kernel plugin
KernelPlugin plugin = kernel.Plugins.AddFromType<WeatherPlugin>(options, "weather_utils");
// Invoke the function
KernelFunction function = kernel.Plugins["weather_utils"]["GetCurrentWeather"];
KernelArguments arguments = new() { ["location"] = new Location("USA", "Boston") };
FunctionResult functionResult = await function.InvokeAsync(kernel, arguments);
// Display the result
Weather weather = functionResult.GetValue<Weather>()!;
Console.WriteLine($"Temperature: {weather.Temperature}, Condition: {weather.Condition}");
}
}
@@ -0,0 +1,81 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Extensions.Configuration;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.Onnx;
namespace SemanticKernel.AotCompatibility;
/// <summary>
/// This class contains samples of how to use ONNX chat completion service in AOT applications.
/// </summary>
internal static class OnnxChatCompletionSamples
{
/// <summary>
/// Sends a prompt to the ONNX model and gets the chat message content.
/// </summary>
public static async Task GetChatMessageContent(IConfigurationRoot config)
{
string chatModelPath = config["Onnx:ModelPath"]!;
string chatModelId = config["Onnx:ModelId"] ?? "phi-3";
// Create kernel builder and add OnnxRuntimeGenAIChatCompletion service.
// If you plan to use the service with Non-ONNX prompt execution settings,
// supply JSON serializer options with a JSON serializer context for this setup.
IKernelBuilder builder = Kernel.CreateBuilder()
.AddOnnxRuntimeGenAIChatCompletion(chatModelId, chatModelPath);
// Build kernel and get the service instance
Kernel kernel = builder.Build();
IChatCompletionService chatService = kernel.GetRequiredService<IChatCompletionService>();
string prompt = "Hello, what is the weather in Boston, USA now?";
OnnxRuntimeGenAIPromptExecutionSettings executionSettings = new()
{
Temperature = 0.7f, // Adjusts creativity level
TopP = 0.9f // Limits token choice diversity
};
// Prompt the ONNX model
ChatMessageContent messageContent = await chatService.GetChatMessageContentAsync(prompt, executionSettings);
// Display the result
Console.WriteLine(messageContent);
}
/// <summary>
/// Sends a prompt to the ONNX model and gets the chat message content in a streaming fashion.
/// </summary>
public static async Task GetStreamingChatMessageContents(IConfigurationRoot config)
{
string chatModelPath = config["Onnx:ModelPath"]!;
string chatModelId = config["Onnx:ModelId"] ?? "phi-3";
// Create kernel builder and add OnnxRuntimeGenAIChatCompletion service.
// If you plan to use the service with Non-ONNX prompt execution settings,
// supply JSON serializer options with a JSON serializer context for this setup.
IKernelBuilder builder = Kernel.CreateBuilder()
.AddOnnxRuntimeGenAIChatCompletion(chatModelId, chatModelPath);
// Build kernel and get the service instance
Kernel kernel = builder.Build();
IChatCompletionService chatService = kernel.GetRequiredService<IChatCompletionService>();
string prompt = "Hello, what is the weather in Boston, USA now?";
OnnxRuntimeGenAIPromptExecutionSettings executionSettings = new()
{
Temperature = 0.7f, // Adjusts creativity level
TopP = 0.9f // Limits token choice diversity
};
// Prompt the ONNX model
await foreach (StreamingChatMessageContent messageContent in chatService.GetStreamingChatMessageContentsAsync(prompt, executionSettings))
{
// Display the result
Console.WriteLine(messageContent);
}
}
}
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft. All rights reserved.
namespace SemanticKernel.AotCompatibility.Plugins;
internal sealed class Location
{
public string Country { get; set; }
public string City { get; set; }
public Location(string country, string city)
{
this.Country = country;
this.City = city;
}
}
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft. All rights reserved.
namespace SemanticKernel.AotCompatibility.Plugins;
internal sealed class Weather
{
public int? Temperature { get; set; }
public string? Condition { get; set; }
public override string ToString() => $"Current weather(temperature: {this.Temperature}F, condition: {this.Condition})";
}
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Microsoft.SemanticKernel;
namespace SemanticKernel.AotCompatibility.Plugins;
internal sealed class WeatherPlugin
{
[KernelFunction]
[Description("Get the current weather in a given location.")]
public Weather GetCurrentWeather(Location location)
{
return location.City switch
{
"Boston" => new Weather { Temperature = 61, Condition = "rainy" },
"London" => new Weather { Temperature = 55, Condition = "cloudy" },
"Miami" => new Weather { Temperature = 80, Condition = "sunny" },
"Tokyo" => new Weather { Temperature = 50, Condition = "sunny" },
"Sydney" => new Weather { Temperature = 75, Condition = "sunny" },
_ => new Weather { Temperature = 31, Condition = "snowing" }
};
}
}
@@ -0,0 +1,56 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Extensions.Configuration;
namespace SemanticKernel.AotCompatibility;
/// <summary>
/// This application demonstrates how to use the Semantic Kernel in AOT applications.
/// </summary>
internal sealed class Program
{
private static async Task<int> Main(string[] args)
{
var config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
bool success = await RunAsync(s_samples, config);
return success ? 1 : 0;
}
private static readonly Func<IConfigurationRoot, Task>[] s_samples =
[
// Samples showing how to create a kernel function and invoke it in AOT applications.
KernelFunctionSamples.CreateFunctionFromLambda,
// Samples showing how to create, import and add a kernel plugin and invoke its functions in AOT applications.
KernelPluginSamples.CreatePluginFromType,
KernelPluginSamples.ImportPluginFromType,
KernelPluginSamples.AddPluginFromType,
// Samples showing how to use ONNX chat completion service in AOT applications.
OnnxChatCompletionSamples.GetChatMessageContent,
OnnxChatCompletionSamples.GetStreamingChatMessageContents
];
private static async Task<bool> RunAsync(IEnumerable<Func<IConfigurationRoot, Task>> functionsToRun, IConfigurationRoot config)
{
bool failed = false;
foreach (var function in functionsToRun)
{
Console.Write($"Running - {function.Method.DeclaringType?.Name}.{function.Method.Name}");
try
{
await function(config);
}
catch (Exception)
{
failed = true;
}
}
return failed;
}
}
@@ -0,0 +1,39 @@
# Native-AOT Samples
This application demonstrates how to use the Semantic Kernel Native-AOT compatible API in a Native-AOT application.
## Running Samples
The samples be run either in a debug mode by just setting a break point and pressing `F5` in Visual Studio (make sure the `AotCompatibility` project is set as the startup project) in which case they are run in a regular CoreCLR application and not in Native-AOT one. This might be useful to understand how the API works and how to use it.
To run the samples in a Native-AOT application, first publish it using the following command: `dotnet publish -r win-x64`. Then, execute the application by running the following command in the terminal: `.\bin\Release\net8.0\win-x64\publish\AotCompatibility.exe`.
## Samples
Most of the samples don't require any additional setup, and can be run as is. However, some of them might require additional configuration.
### 1. [ONNX Chat Completion Service](./OnnxChatCompletionSamples.cs)
To configure the sample, you need to download the ONNX model from the Hugging Face repository. Go to a directory of your choice where the model should be downloaded and run the following command:
```powershell
git clone https://huggingface.co/microsoft/Phi-3-mini-4k-instruct-onnx
```
> [!IMPORTANT]
The `Phi-3` model may be too large to download using the `git clone` command unless you have the [git-lfs extension](https://git-lfs.com/) installed.
You might need to download it manually using the following link: [Phi-3-Mini-4k CPU](https://huggingface.co/microsoft/Phi-3-mini-4k-instruct-onnx/resolve/main/cpu_and_mobile/cpu-int4-rtn-block-32/phi3-mini-4k-instruct-cpu-int4-rtn-block-32.onnx.data?download=true) (approximately 2.7 GB).
After downloading the model, you need to configure the sample by setting the `Onnx:ModelPath` and `Onnx:ModelId` secrets.
The `Onnx:ModelPath` should point to the directory where the model was downloaded, and the `Onnx:ModelId` should be set to `phi-3`.
The secrets can be set using [Secret Manager](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets#secret-manager) in the following way:
```powershell
dotnet user-secrets set "Onnx:ModelId" "phi-3"
dotnet user-secrets set "Onnx:ModelPath" "C:\path\to\huggingface\Phi-3-mini-4k-instruct-onnx\cpu_and_mobile\cpu-int4-rtn-block-32"
```
### AOT Compatibility
At the moment, the following Semantic Kernel packages are AOT compatible:
| Package | AOT compatible |
|--------------------------|----------------|
| SemanticKernel.Abstractions | ✔️ |
| SemanticKernel.Core | ✔️ |
| Connectors.Onnx | ✔️ |
Other packages are not AOT compatible yet, but we plan to make them compatible in the future.