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,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>5ee045b0-aea3-4f08-8d31-32d1a6f8fed0</UserSecretsId>
<NoWarn>$(NoWarn);CA2007,CA2208,CS1591,IDE0009,IDE0055,IDE0073,VSTHRD111,SKEXP0001</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Connectors\Connectors.AzureOpenAI\Connectors.AzureOpenAI.csproj" />
<ProjectReference Include="..\..\..\src\Connectors\Connectors.OpenAI\Connectors.OpenAI.csproj" />
<ProjectReference Include="..\..\..\src\SemanticKernel.Abstractions\SemanticKernel.Abstractions.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Properties\launchSettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel.DataAnnotations;
namespace HomeAutomation.Options;
/// <summary>
/// Azure OpenAI settings.
/// </summary>
public sealed class AzureOpenAIOptions
{
public const string SectionName = "AzureOpenAI";
[Required]
public string ChatDeploymentName { get; set; } = string.Empty;
[Required]
public string Endpoint { get; set; } = string.Empty;
[Required]
public string ApiKey { get; set; } = string.Empty;
}
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel.DataAnnotations;
namespace HomeAutomation.Options;
/// <summary>
/// OpenAI settings.
/// </summary>
public sealed class OpenAIOptions
{
public const string SectionName = "OpenAI";
[Required]
public string ChatModelId { get; set; } = string.Empty;
[Required]
public string ApiKey { get; set; } = string.Empty;
}
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Microsoft.SemanticKernel;
namespace HomeAutomation.Plugins;
/// <summary>
/// Simple plugin to illustrate creating plugins which have dependencies
/// that can be resolved through dependency injection.
/// </summary>
public class MyAlarmPlugin(MyTimePlugin timePlugin)
{
[KernelFunction, Description("Sets an alarm at the provided time")]
public void SetAlarm(string time)
{
// Code to actually set the alarm using the time plugin would be placed here
_ = timePlugin;
}
}
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Microsoft.SemanticKernel;
namespace HomeAutomation.Plugins;
/// <summary>
/// Class that represents a controllable light.
/// </summary>
[Description("Represents a light")]
public class MyLightPlugin(bool turnedOn = false)
{
private bool _turnedOn = turnedOn;
[KernelFunction, Description("Returns whether this light is on")]
public bool IsTurnedOn() => _turnedOn;
[KernelFunction, Description("Turn on this light")]
public void TurnOn() => _turnedOn = true;
[KernelFunction, Description("Turn off this light")]
public void TurnOff() => _turnedOn = false;
}
@@ -0,0 +1,15 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Microsoft.SemanticKernel;
namespace HomeAutomation.Plugins;
/// <summary>
/// Simple plugin that just returns the time.
/// </summary>
public class MyTimePlugin
{
[KernelFunction, Description("Get the current time")]
public DateTimeOffset Time() => DateTimeOffset.Now;
}
@@ -0,0 +1,106 @@
/*
Copyright (c) Microsoft. All rights reserved.
Example that demonstrates how to use Semantic Kernel in conjunction with dependency injection.
Loads app configuration from:
- appsettings.json.
- appsettings.{Environment}.json.
- Secret Manager when the app runs in the "Development" environment (set through the DOTNET_ENVIRONMENT variable).
- Environment variables.
- Command-line arguments.
*/
using HomeAutomation.Options;
using HomeAutomation.Plugins;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
// For Azure OpenAI configuration
#pragma warning disable IDE0005 // Using directive is unnecessary.
using Microsoft.SemanticKernel.Connectors.OpenAI;
namespace HomeAutomation;
internal static class Program
{
internal static async Task Main(string[] args)
{
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Configuration.AddUserSecrets<Worker>();
// Actual code to execute is found in Worker class
builder.Services.AddHostedService<Worker>();
// Get configuration
builder.Services.AddOptions<OpenAIOptions>()
.Bind(builder.Configuration.GetSection(OpenAIOptions.SectionName))
.ValidateDataAnnotations()
.ValidateOnStart();
/* Alternatively, you can use plain, Azure OpenAI after loading AzureOpenAIOptions instead of OpenAI
builder.Services.AddOptions<AzureOpenAIOptions>()
.Bind(builder.Configuration.GetSection(AzureOpenAIOptions.SectionName))
.ValidateDataAnnotations()
.ValidateOnStart();
*/
// Chat completion service that kernels will use
builder.Services.AddSingleton<IChatCompletionService>(sp =>
{
OpenAIOptions openAIOptions = sp.GetRequiredService<IOptions<OpenAIOptions>>().Value;
// A custom HttpClient can be provided to this constructor
return new OpenAIChatCompletionService(openAIOptions.ChatModelId, openAIOptions.ApiKey);
/* Alternatively, you can use plain, Azure OpenAI after loading AzureOpenAIOptions instead
of OpenAI options with builder.Services.AddOptions:
AzureOpenAIOptions azureOpenAIOptions = sp.GetRequiredService<IOptions<AzureOpenAIOptions>>().Value;
return new AzureOpenAIChatCompletionService(azureOpenAIOptions.ChatDeploymentName, azureOpenAIOptions.Endpoint, azureOpenAIOptions.ApiKey);
*/
});
// Add plugins that can be used by kernels
// The plugins are added as singletons so that they can be used by multiple kernels
builder.Services.AddSingleton<MyTimePlugin>();
builder.Services.AddSingleton<MyAlarmPlugin>();
builder.Services.AddKeyedSingleton<MyLightPlugin>("OfficeLight");
builder.Services.AddKeyedSingleton<MyLightPlugin>("PorchLight", (sp, key) =>
{
return new MyLightPlugin(turnedOn: true);
});
/* To add an OpenAI or OpenAPI plugin, you need to be using Microsoft.SemanticKernel.Plugins.OpenApi.
Then create a temporary kernel, use it to load the plugin and add it as keyed singleton.
Kernel kernel = new();
KernelPlugin openAIPlugin = await kernel.ImportPluginFromOpenAIAsync("<plugin name>", new Uri("<OpenAI-plugin>"));
builder.Services.AddKeyedSingleton<KernelPlugin>("MyImportedOpenAIPlugin", openAIPlugin);
KernelPlugin openApiPlugin = await kernel.ImportPluginFromOpenApiAsync("<plugin name>", new Uri("<OpenAPI-plugin>"));
builder.Services.AddKeyedSingleton<KernelPlugin>("MyImportedOpenApiPlugin", openApiPlugin);*/
// Add a home automation kernel to the dependency injection container
builder.Services.AddKeyedTransient<Kernel>("HomeAutomationKernel", (sp, key) =>
{
// Create a collection of plugins that the kernel will use
KernelPluginCollection pluginCollection = [];
pluginCollection.AddFromObject(sp.GetRequiredService<MyTimePlugin>());
pluginCollection.AddFromObject(sp.GetRequiredService<MyAlarmPlugin>());
pluginCollection.AddFromObject(sp.GetRequiredKeyedService<MyLightPlugin>("OfficeLight"), "OfficeLight");
pluginCollection.AddFromObject(sp.GetRequiredKeyedService<MyLightPlugin>("PorchLight"), "PorchLight");
// When created by the dependency injection container, Semantic Kernel logging is included by default
return new Kernel(sp, pluginCollection);
});
using IHost host = builder.Build();
await host.RunAsync();
}
}
@@ -0,0 +1,40 @@
# "House Automation" example illustrating how to use Semantic Kernel with dependency injection
This example demonstrates a few dependency injection patterns that can be used with Semantic Kernel.
## Configuring Secrets
The example require credentials to access OpenAI or Azure OpenAI.
If you have set up those credentials as secrets within Secret Manager or through environment variables for other samples from the solution in which this project is found, they will be re-used.
### To set your secrets with Secret Manager:
```
cd dotnet/samples/Demos/HouseAutomation
dotnet user-secrets init
dotnet user-secrets set "OpenAI:ChatModelId" "..."
dotnet user-secrets set "OpenAI:ApiKey" "..."
dotnet user-secrets set "AzureOpenAI:ChatDeploymentName" "..."
dotnet user-secrets set "AzureOpenAI:Endpoint" "https://... .openai.azure.com/"
dotnet user-secrets set "AzureOpenAI:ApiKey" "..."
```
### To set your secrets with environment variables
Use these names:
```
# OpenAI
OpenAI__ChatModelId
OpenAI__ApiKey
# Azure OpenAI
AzureOpenAI__ChatDeploymentName
AzureOpenAI__Endpoint
AzureOpenAI__ApiKey
```
@@ -0,0 +1,54 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
namespace HomeAutomation;
/// <summary>
/// Actual code to run.
/// </summary>
internal sealed class Worker(
IHostApplicationLifetime hostApplicationLifetime,
[FromKeyedServices("HomeAutomationKernel")] Kernel kernel) : BackgroundService
{
private readonly IHostApplicationLifetime _hostApplicationLifetime = hostApplicationLifetime;
private readonly Kernel _kernel = kernel;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// Get chat completion service
var chatCompletionService = _kernel.GetRequiredService<IChatCompletionService>();
// Enable auto function calling
OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};
Console.WriteLine("Ask questions or give instructions to the copilot such as:\n" +
"- What time is it?\n" +
"- Turn on the porch light.\n" +
"- If it's before 7:00 pm, turn on the office light.\n" +
"- Which light is currently on?\n" +
"- Set an alarm for 6:00 am.\n");
Console.Write("> ");
string? input = null;
while ((input = Console.ReadLine()) is not null)
{
Console.WriteLine();
ChatMessageContent chatResult = await chatCompletionService.GetChatMessageContentAsync(input,
openAIPromptExecutionSettings, _kernel, stoppingToken);
Console.Write($"\n>>> Result: {chatResult}\n\n> ");
}
_hostApplicationLifetime.StopApplication();
}
}
@@ -0,0 +1,7 @@
{
"AzureOpenAI": {
"ChatDeploymentName": "",
"Endpoint": ""
// "ApiKey": "" /// Set this value in appsettings.Development.json, or using "dotnet user-secrets"
}
}