Skip to content

Commit 22bfdf8

Browse files
authored
.Net: Move documentation examples from documentation repo into SK repo (#4704)
### Motivation and Context In order to keep documentation examples up to date, moving them to a repo where they will actually be built and run. ### Description Move documentation examples from doc repo to this one. ### Contribution Checklist - [ ] The code builds clean without any errors or warnings - [ ] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone 😄
1 parent 7170f0d commit 22bfdf8

File tree

68 files changed

+3613
-46
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+3613
-46
lines changed

dotnet/Directory.Packages.props

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,14 @@
1313
<PackageVersion Include="Markdig" Version="0.34.0" />
1414
<PackageVersion Include="Handlebars.Net" Version="2.1.4" />
1515
<PackageVersion Include="JsonSchema.Net.Generation" Version="3.5.1" />
16+
<PackageVersion Include="Microsoft.Azure.Functions.Worker" Version="1.20.1" />
17+
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
1618
<PackageVersion Include="Microsoft.Azure.Kusto.Data" Version="11.3.5" />
19+
<PackageVersion Include="Microsoft.Azure.WebJobs.Extensions.OpenApi" Version="1.5.1" />
1720
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="[1.1.0, )" />
1821
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
22+
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.3.0" />
23+
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0" />
1924
<PackageVersion Include="Microsoft.Bcl.TimeProvider" Version="8.0.1" />
2025
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="8.0.0" />
2126
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />

dotnet/SK-dotnet.sln

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,9 @@ EndProject
116116
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "System", "System", "{3CDE10B2-AE8F-4FC4-8D55-92D4AD32E144}"
117117
ProjectSection(SolutionItems) = preProject
118118
src\InternalUtilities\src\System\EnvExtensions.cs = src\InternalUtilities\src\System\EnvExtensions.cs
119-
src\InternalUtilities\src\System\InternalTypeConverter.cs = src\InternalUtilities\src\System\InternalTypeConverter.cs
120-
src\InternalUtilities\src\System\TypeConverterFactory.cs = src\InternalUtilities\src\System\TypeConverterFactory.cs
121-
src\InternalUtilities\src\System\NonNullCollection.cs = src\InternalUtilities\src\System\NonNullCollection.cs
122119
EndProjectSection
123120
EndProject
124121
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Type", "Type", "{E85EA4D0-BB7E-4DFD-882F-A76EB8C0B8FF}"
125-
ProjectSection(SolutionItems) = preProject
126-
src\InternalUtilities\src\Type\TypeExtensions.cs = src\InternalUtilities\src\Type\TypeExtensions.cs
127-
EndProjectSection
128122
EndProject
129123
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Plugins.Core", "src\Plugins\Plugins.Core\Plugins.Core.csproj", "{0D0C4DAD-E6BC-4504-AE3A-EEA4E35920C1}"
130124
EndProject
@@ -197,6 +191,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Experimental.Orchestration.
197191
EndProject
198192
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Experimental.Orchestration.Flow.UnitTests", "src\Experimental\Orchestration.Flow.UnitTests\Experimental.Orchestration.Flow.UnitTests.csproj", "{731CC542-8BE9-42D4-967D-99206EC2B310}"
199193
EndProject
194+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DocumentationExamples", "samples\DocumentationExamples\DocumentationExamples.csproj", "{A8E0D3B2-49D7-4DF6-BF91-B234C1C5E25D}"
195+
EndProject
196+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CreateChatGptPlugin", "samples\CreateChatGptPlugin\Solution\CreateChatGptPlugin.csproj", "{87AB5AF5-5783-4372-9789-664895E0A2FF}"
197+
EndProject
200198
Global
201199
GlobalSection(SolutionConfigurationPlatforms) = preSolution
202200
Debug|Any CPU = Debug|Any CPU
@@ -460,6 +458,18 @@ Global
460458
{731CC542-8BE9-42D4-967D-99206EC2B310}.Publish|Any CPU.Build.0 = Debug|Any CPU
461459
{731CC542-8BE9-42D4-967D-99206EC2B310}.Release|Any CPU.ActiveCfg = Release|Any CPU
462460
{731CC542-8BE9-42D4-967D-99206EC2B310}.Release|Any CPU.Build.0 = Release|Any CPU
461+
{A8E0D3B2-49D7-4DF6-BF91-B234C1C5E25D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
462+
{A8E0D3B2-49D7-4DF6-BF91-B234C1C5E25D}.Debug|Any CPU.Build.0 = Debug|Any CPU
463+
{A8E0D3B2-49D7-4DF6-BF91-B234C1C5E25D}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
464+
{A8E0D3B2-49D7-4DF6-BF91-B234C1C5E25D}.Publish|Any CPU.Build.0 = Debug|Any CPU
465+
{A8E0D3B2-49D7-4DF6-BF91-B234C1C5E25D}.Release|Any CPU.ActiveCfg = Release|Any CPU
466+
{A8E0D3B2-49D7-4DF6-BF91-B234C1C5E25D}.Release|Any CPU.Build.0 = Release|Any CPU
467+
{87AB5AF5-5783-4372-9789-664895E0A2FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
468+
{87AB5AF5-5783-4372-9789-664895E0A2FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
469+
{87AB5AF5-5783-4372-9789-664895E0A2FF}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
470+
{87AB5AF5-5783-4372-9789-664895E0A2FF}.Publish|Any CPU.Build.0 = Debug|Any CPU
471+
{87AB5AF5-5783-4372-9789-664895E0A2FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
472+
{87AB5AF5-5783-4372-9789-664895E0A2FF}.Release|Any CPU.Build.0 = Release|Any CPU
463473
EndGlobalSection
464474
GlobalSection(SolutionProperties) = preSolution
465475
HideSolutionNode = FALSE
@@ -528,6 +538,8 @@ Global
528538
{B0CE8C69-EC56-4825-94AB-01CA7E8BA55B} = {A2357CF8-3BB9-45A1-93F1-B366C9B63658}
529539
{3A4B8F90-3E74-43E0-800C-84F8AA9B5BF3} = {A2357CF8-3BB9-45A1-93F1-B366C9B63658}
530540
{731CC542-8BE9-42D4-967D-99206EC2B310} = {A2357CF8-3BB9-45A1-93F1-B366C9B63658}
541+
{A8E0D3B2-49D7-4DF6-BF91-B234C1C5E25D} = {FA3720F1-C99A-49B2-9577-A940257098BF}
542+
{87AB5AF5-5783-4372-9789-664895E0A2FF} = {FA3720F1-C99A-49B2-9577-A940257098BF}
531543
EndGlobalSection
532544
GlobalSection(ExtensibilityGlobals) = postSolution
533545
SolutionGuid = {FBDC56A3-86AD-4323-AA0F-201E59123B83}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[*.cs]
2+
dotnet_diagnostic.CA1016.severity = none
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
**/bin
2+
**/obj
3+
local.settings.json
4+
azure-function/appsettings.json
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Semantic Kernel OpenAI plugin starter
2+
3+
This project provides starter code to create a OpenAI plugin. It includes the following components:
4+
5+
- An endpoint that serves up an ai-plugin.json file for ChatGPT to discover the plugin
6+
- A generator that automatically converts prompts into prompt endpoints
7+
- The ability to add additional native functions as endpoints to the plugin
8+
9+
## Prerequisites
10+
11+
- [.NET 6](https://dotnet.microsoft.com/download/dotnet/8.0) is required to run this starter.
12+
- [Azure Functions Core Tools](https://www.npmjs.com/package/azure-functions-core-tools) is required to run this starter.
13+
- Install the recommended extensions
14+
- [C#](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp)
15+
- [Semantic Kernel Tools](https://marketplace.visualstudio.com/items?itemName=ms-semantic-kernel.semantic-kernel) (optional)
16+
17+
## Configuring the starter
18+
19+
To configure the starter, you need to provide the following information:
20+
21+
- Define the properties of the plugin in the appsettings.json file.
22+
- Enter the API key for your AI endpoint in the [local.settings.json](./azure-function/local.settings.json.example) file.
23+
24+
### Using appsettings.json
25+
26+
Configure an OpenAI endpoint
27+
28+
1. Copy [settings.json.openai-example](./azure-function/config-samples/appsettings.json.openai-example) to `./appsettings.json`
29+
1. Edit the `kernel` object to add your OpenAI endpoint configuration
30+
1. Edit the `aiPlugin` object to define the properties that get exposed in the ai-plugin.json file
31+
32+
Configure an Azure OpenAI endpoint
33+
34+
1. Copy [settings.json.azure-example](./azure-function/config-samples/appsettings.json.azure-example) to `./appsettings.json`
35+
1. Edit the `kernel` object to add your Azure OpenAI endpoint configuration
36+
1. Edit the `aiPlugin` object to define the properties that get exposed in the ai-plugin.json file
37+
38+
### Using local.settings.json
39+
40+
1. Copy [local.settings.json.example](./azure-function/local.settings.json.example) to `./azure-function/local.settings.json`
41+
1. Edit the `Values` object to add your OpenAI endpoint configuration in the `apiKey` property
42+
43+
## Running the starter
44+
45+
To run the Azure Functions application just hit `F5`.
46+
47+
To build and run the Azure Functions application from a terminal use the following commands:
48+
49+
```powershell
50+
cd azure-function
51+
dotnet build
52+
cd bin/Debug/net8.0
53+
func host start
54+
```
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using System.Net;
4+
using Microsoft.Azure.Functions.Worker;
5+
using Microsoft.Azure.Functions.Worker.Http;
6+
using Models;
7+
8+
public class AIPluginJson
9+
{
10+
[Function("GetAIPluginJson")]
11+
public HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = ".well-known/ai-plugin.json")] HttpRequestData req)
12+
{
13+
var currentDomain = $"{req.Url.Scheme}://{req.Url.Host}:{req.Url.Port}";
14+
15+
HttpResponseData response = req.CreateResponse(HttpStatusCode.OK);
16+
response.Headers.Add("Content-Type", "application/json");
17+
18+
var appSettings = AppSettings.LoadSettings();
19+
20+
// serialize app settings to json using System.Text.Json
21+
var json = System.Text.Json.JsonSerializer.Serialize(appSettings.AIPlugin);
22+
23+
// replace {url} with the current domain
24+
json = json.Replace("{url}", currentDomain, StringComparison.OrdinalIgnoreCase);
25+
26+
response.WriteString(json);
27+
28+
return response;
29+
}
30+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<Project>
2+
<PropertyGroup>
3+
<!-- Default properties inherited by all projects. Projects can override. -->
4+
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
5+
<EnableNETAnalyzers>true</EnableNETAnalyzers>
6+
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
7+
<AnalysisLevel>latest</AnalysisLevel>
8+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
9+
<LangVersion>11</LangVersion>
10+
<Nullable>enable</Nullable>
11+
<ImplicitUsings>disable</ImplicitUsings>
12+
<NoWarn>CS1591,CA1852,CA1050</NoWarn>
13+
</PropertyGroup>
14+
15+
<PropertyGroup>
16+
<!-- Disable NuGet packaging by default. Projects can override. -->
17+
<IsPackable>disable</IsPackable>
18+
</PropertyGroup>
19+
20+
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
21+
<DebugSymbols>true</DebugSymbols>
22+
<DebugType>full</DebugType>
23+
</PropertyGroup>
24+
25+
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
26+
<DebugType>portable</DebugType>
27+
</PropertyGroup>
28+
29+
<PropertyGroup>
30+
<RepoRoot>$([System.IO.Path]::GetDirectoryName($([MSBuild]::GetPathOfFileAbove('.gitignore', '$(MSBuildThisFileDirectory)'))))</RepoRoot>
31+
</PropertyGroup>
32+
33+
</Project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project>
2+
<!-- Direct all packages under 'dotnet' to get versions from Directory.Packages.props -->
3+
<!-- using Central Package Management feature -->
4+
<!-- https://learn.microsoft.com/en-us/nuget/consume-packages/Central-Package-Management -->
5+
<Sdk Name="Microsoft.Build.CentralPackageVersions" Version="2.1.3" />
6+
7+
<!-- Only run 'dotnet format' on dev machines, Release builds. Skip on GitHub Actions -->
8+
<!-- as this runs in its own Actions job. -->
9+
<Target Name="DotnetFormatOnBuild" BeforeTargets="Build"
10+
Condition=" '$(Configuration)' == 'Release' AND '$(GITHUB_ACTIONS)' == '' ">
11+
<Message Text="Running dotnet format" Importance="high" />
12+
<Exec Command="dotnet format --no-restore -v diag $(ProjectFileName)" />
13+
</Target>
14+
15+
<Target Name="AddInternalsVisibleTo" BeforeTargets="BeforeCompile">
16+
<!-- Handle Add InternalsVisibleTo to any targets that don't support it. -->
17+
<ItemGroup Condition="'@(InternalsVisibleTo->Count())' &gt; 0 AND $([MSBuild]::VersionLessThan($(NETCoreSdkVersion), '5.0.0'))">
18+
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
19+
<_Parameter1 Condition="'%(InternalsVisibleTo.PublicKey)' != ''">%(InternalsVisibleTo.Identity), PublicKey="%(InternalsVisibleTo.PublicKey)</_Parameter1>
20+
<_Parameter1 Condition="'%(InternalsVisibleTo.PublicKey)' == ''">%(InternalsVisibleTo.Identity)</_Parameter1>
21+
<_Parameter1_TypeName>System.String</_Parameter1_TypeName>
22+
</AssemblyAttribute>
23+
</ItemGroup>
24+
</Target>
25+
</Project>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using System.Net;
4+
using System.Reflection;
5+
using System.Text.Json;
6+
using Microsoft.Azure.Functions.Worker.Http;
7+
using Microsoft.Extensions.Logging;
8+
using Microsoft.SemanticKernel;
9+
10+
namespace Plugins.AzureFunctions.Extensions;
11+
12+
public class AIPluginRunner
13+
{
14+
private readonly ILogger<AIPluginRunner> _logger;
15+
private readonly Kernel _kernel;
16+
17+
public AIPluginRunner(Kernel kernel, ILoggerFactory loggerFactory)
18+
{
19+
this._kernel = kernel;
20+
this._logger = loggerFactory.CreateLogger<AIPluginRunner>();
21+
}
22+
23+
/// <summary>
24+
/// Runs a prompt using the operationID and returns back an HTTP response.
25+
/// </summary>
26+
/// <param name="req"></param>
27+
/// <param name="pluginName"></param>
28+
/// <param name="functionName"></param>
29+
public async Task<HttpResponseData> RunAIPluginOperationAsync<T>(HttpRequestData req, string pluginName, string functionName)
30+
{
31+
KernelArguments arguments = ConvertToKernelArguments((await JsonSerializer.DeserializeAsync<T>(req.Body).ConfigureAwait(true))!);
32+
33+
var response = req.CreateResponse(HttpStatusCode.OK);
34+
response.Headers.Add("Content-Type", "text/plain;charset=utf-8");
35+
await response.WriteStringAsync(
36+
(await this._kernel.InvokeAsync(pluginName, functionName, arguments).ConfigureAwait(false)).ToString()
37+
).ConfigureAwait(false);
38+
return response;
39+
}
40+
41+
// Method to convert model to dictionary
42+
private static KernelArguments ConvertToKernelArguments<T>(T model)
43+
{
44+
{
45+
var arguments = new KernelArguments();
46+
foreach (PropertyInfo property in typeof(T).GetProperties())
47+
{
48+
if (property.GetValue(model) != null)
49+
{
50+
arguments.Add(property.Name, property.GetValue(model));
51+
}
52+
}
53+
return arguments;
54+
}
55+
}
56+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.SemanticKernel;
5+
using Models;
6+
7+
internal static class KernelBuilderExtensions
8+
{
9+
/// <summary>
10+
/// Adds a chat completion service to the list. It can be either an OpenAI or Azure OpenAI backend service.
11+
/// </summary>
12+
/// <param name="kernelBuilder"></param>
13+
/// <param name="kernelSettings"></param>
14+
/// <exception cref="ArgumentException"></exception>
15+
internal static IServiceCollection WithChatCompletionService(this IServiceCollection kernelBuilder, KernelSettings kernelSettings)
16+
{
17+
switch (kernelSettings.ServiceType.ToUpperInvariant())
18+
{
19+
case ServiceTypes.AzureOpenAI:
20+
kernelBuilder.AddAzureOpenAIChatCompletion(deploymentName: kernelSettings.DeploymentOrModelId, modelId: kernelSettings.DeploymentOrModelId, endpoint: kernelSettings.Endpoint, apiKey: kernelSettings.ApiKey, serviceId: kernelSettings.ServiceId);
21+
break;
22+
23+
case ServiceTypes.OpenAI:
24+
kernelBuilder.AddOpenAIChatCompletion(modelId: kernelSettings.DeploymentOrModelId, apiKey: kernelSettings.ApiKey, orgId: kernelSettings.OrgId, serviceId: kernelSettings.ServiceId);
25+
break;
26+
27+
default:
28+
throw new ArgumentException($"Invalid service type value: {kernelSettings.ServiceType}");
29+
}
30+
31+
return kernelBuilder;
32+
}
33+
}

0 commit comments

Comments
 (0)