Skip to content

Commit

Permalink
.Net: Time Plugin Demo (#6200)
Browse files Browse the repository at this point in the history
# Time Plugin - Demo Application

This is an example how you can easily use Plugins with the Power of Auto
Function Calling from AI Models.

Here we have a simple Time Plugin created in C# that can be called from
the AI Model to get the current time.
  • Loading branch information
RogerBarreto committed May 14, 2024
1 parent af207dc commit 132693c
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 15 deletions.
33 changes: 18 additions & 15 deletions dotnet/SK-dotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -294,14 +294,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PromptTemplates.Liquid.Unit
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Functions.Prompty.UnitTests", "src\Functions\Functions.Prompty.UnitTests\Functions.Prompty.UnitTests.csproj", "{AD787471-5E43-44DF-BF3E-5CD26C765B4E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ContentSafety", "samples\Demos\ContentSafety\ContentSafety.csproj", "{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ContentSafety", "samples\Demos\ContentSafety\ContentSafety.csproj", "{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Concepts", "samples\Concepts\Concepts.csproj", "{925B1185-8B58-4E2D-95C9-4CA0BA9364E5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionInvocationApproval", "samples\Demos\FunctionInvocationApproval\FunctionInvocationApproval.csproj", "{6B56D8EE-9991-43E3-90B2-B8F5C5CE77C2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CodeInterpreterPlugin", "samples\Demos\CodeInterpreterPlugin\CodeInterpreterPlugin.csproj", "{3ED53702-0E53-473A-A0F4-645DB33541C2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TimePlugin", "samples\Demos\TimePlugin\TimePlugin.csproj", "{F312FCE1-12D7-4DEF-BC29-2FF6618509F3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -669,6 +671,12 @@ Global
{1D98CF16-5156-40F0-91F0-76294B153DB3}.Publish|Any CPU.Build.0 = Debug|Any CPU
{1D98CF16-5156-40F0-91F0-76294B153DB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D98CF16-5156-40F0-91F0-76294B153DB3}.Release|Any CPU.Build.0 = Release|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Debug|Any CPU.Build.0 = Debug|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Publish|Any CPU.Build.0 = Debug|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Release|Any CPU.ActiveCfg = Release|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Release|Any CPU.Build.0 = Release|Any CPU
{12B06019-740B-466D-A9E0-F05BC123A47D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12B06019-740B-466D-A9E0-F05BC123A47D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{12B06019-740B-466D-A9E0-F05BC123A47D}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
Expand Down Expand Up @@ -699,18 +707,6 @@ Global
{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2}.Publish|Any CPU.Build.0 = Debug|Any CPU
{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2}.Release|Any CPU.Build.0 = Release|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Debug|Any CPU.Build.0 = Debug|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Publish|Any CPU.Build.0 = Debug|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Release|Any CPU.ActiveCfg = Release|Any CPU
{87DA81FE-112E-4AF5-BEFB-0B91B993F749}.Release|Any CPU.Build.0 = Release|Any CPU
{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2}.Publish|Any CPU.Build.0 = Debug|Any CPU
{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2}.Release|Any CPU.Build.0 = Release|Any CPU
{925B1185-8B58-4E2D-95C9-4CA0BA9364E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{925B1185-8B58-4E2D-95C9-4CA0BA9364E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{925B1185-8B58-4E2D-95C9-4CA0BA9364E5}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
Expand All @@ -729,6 +725,12 @@ Global
{3ED53702-0E53-473A-A0F4-645DB33541C2}.Publish|Any CPU.Build.0 = Debug|Any CPU
{3ED53702-0E53-473A-A0F4-645DB33541C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3ED53702-0E53-473A-A0F4-645DB33541C2}.Release|Any CPU.Build.0 = Release|Any CPU
{F312FCE1-12D7-4DEF-BC29-2FF6618509F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F312FCE1-12D7-4DEF-BC29-2FF6618509F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F312FCE1-12D7-4DEF-BC29-2FF6618509F3}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{F312FCE1-12D7-4DEF-BC29-2FF6618509F3}.Publish|Any CPU.Build.0 = Debug|Any CPU
{F312FCE1-12D7-4DEF-BC29-2FF6618509F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F312FCE1-12D7-4DEF-BC29-2FF6618509F3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -819,16 +821,17 @@ Global
{5C813F83-9FD8-462A-9B38-865CA01C384C} = {5D4C0700-BBB5-418F-A7B2-F392B9A18263}
{D5E4C960-53B3-4C35-99C1-1BA97AECC489} = {5D4C0700-BBB5-418F-A7B2-F392B9A18263}
{1D98CF16-5156-40F0-91F0-76294B153DB3} = {FA3720F1-C99A-49B2-9577-A940257098BF}
{87DA81FE-112E-4AF5-BEFB-0B91B993F749} = {FA3720F1-C99A-49B2-9577-A940257098BF}
{77E141BA-AF5E-4C01-A970-6C07AC3CD55A} = {4D3DAE63-41C6-4E1C-A35A-E77BDFC40675}
{12B06019-740B-466D-A9E0-F05BC123A47D} = {9ECD1AA0-75B3-4E25-B0B5-9F0945B64974}
{66D94E25-9B63-4C29-B7A1-3DFA17A90745} = {078F96B4-09E1-4E0E-B214-F71A4F4BF633}
{CC6DEE89-57AA-494D-B40D-B09E1CCC6FAD} = {078F96B4-09E1-4E0E-B214-F71A4F4BF633}
{AD787471-5E43-44DF-BF3E-5CD26C765B4E} = {9ECD1AA0-75B3-4E25-B0B5-9F0945B64974}
{87DA81FE-112E-4AF5-BEFB-0B91B993F749} = {FA3720F1-C99A-49B2-9577-A940257098BF}
{77E141BA-AF5E-4C01-A970-6C07AC3CD55A} = {4D3DAE63-41C6-4E1C-A35A-E77BDFC40675}
{6EF9663D-976C-4A27-B8D3-8B1E63BA3BF2} = {5D4C0700-BBB5-418F-A7B2-F392B9A18263}
{925B1185-8B58-4E2D-95C9-4CA0BA9364E5} = {FA3720F1-C99A-49B2-9577-A940257098BF}
{6B56D8EE-9991-43E3-90B2-B8F5C5CE77C2} = {5D4C0700-BBB5-418F-A7B2-F392B9A18263}
{3ED53702-0E53-473A-A0F4-645DB33541C2} = {5D4C0700-BBB5-418F-A7B2-F392B9A18263}
{F312FCE1-12D7-4DEF-BC29-2FF6618509F3} = {5D4C0700-BBB5-418F-A7B2-F392B9A18263}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FBDC56A3-86AD-4323-AA0F-201E59123B83}
Expand Down
68 changes: 68 additions & 0 deletions dotnet/samples/Demos/TimePlugin/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) Microsoft. All rights reserved.
#pragma warning disable VSTHRD111 // Use ConfigureAwait(bool)
#pragma warning disable CA1050 // Declare types in namespaces
#pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task

using System.ComponentModel;
using Microsoft.Extensions.Configuration;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;

var config = new ConfigurationBuilder()
.AddUserSecrets<Program>()
.AddEnvironmentVariables()
.Build()
?? throw new InvalidOperationException("Configuration is not provided.");

ArgumentNullException.ThrowIfNull(config["OpenAI:ChatModelId"], "OpenAI:ChatModelId");
ArgumentNullException.ThrowIfNull(config["OpenAI:ApiKey"], "OpenAI:ApiKey");

var kernelBuilder = Kernel.CreateBuilder().AddOpenAIChatCompletion(
modelId: config["OpenAI:ChatModelId"]!,
apiKey: config["OpenAI:ApiKey"]!);

kernelBuilder.Plugins.AddFromType<TimeInformationPlugin>();
var kernel = kernelBuilder.Build();

// Get chat completion service
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

// Enable auto function calling
OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
{
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};

Console.WriteLine("Ask questions to use the Time Plugin such as:\n" +
"- What time is it?");

ChatHistory chatHistory = [];
string? input = null;
while (true)
{
Console.Write("\nUser > ");
input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
// Leaves if the user hit enter without typing any word
break;
}
chatHistory.AddUserMessage(input);
var chatResult = await chatCompletionService.GetChatMessageContentAsync(chatHistory, openAIPromptExecutionSettings, kernel);
Console.Write($"\nAssistant > {chatResult}\n");
}

/// <summary>
/// A plugin that returns the current time.
/// </summary>
public class TimeInformationPlugin
{
/// <summary>
/// Retrieves the current time in UTC.
/// </summary>
/// <returns>The current time in UTC. </returns>
[KernelFunction, Description("Retrieves the current time in UTC.")]
public string GetCurrentUtcTime()
=> DateTime.UtcNow.ToString("R");
}
74 changes: 74 additions & 0 deletions dotnet/samples/Demos/TimePlugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Time Plugin - Demo Application

This is an example how you can easily use Plugins with the Power of Auto Function Calling from AI Models.

Here we have a simple Time Plugin created in C# that can be called from the AI Model to get the current time.


## Semantic Kernel Features Used

- [Plugin](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/src/SemanticKernel.Abstractions/Functions/KernelPlugin.cs) - Creating a Plugin from a native C# Booking class to be used by the Kernel to interact with Bookings API.
- [Chat Completion Service](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/src/SemanticKernel.Abstractions/AI/ChatCompletion/IChatCompletionService.cs) - Using the Chat Completion Service [OpenAI Connector implementation](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/src/Connectors/Connectors.OpenAI/ChatCompletion/OpenAIChatCompletionService.cs) to generate responses from the LLM.
- [Chat History](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/src/SemanticKernel.Abstractions/AI/ChatCompletion/ChatHistory.cs) Using the Chat History abstraction to create, update and retrieve chat history from Chat Completion Models.
- [Auto Function Calling](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/KernelSyntaxExamples/Example59_OpenAIFunctionCalling.cs) Enables the LLM to have knowledge of current importedUsing the Function Calling feature automatically call the Booking Plugin from the LLM.

## Prerequisites

- [.NET 8](https://dotnet.microsoft.com/download/dotnet/8.0).

### Function Calling Enabled Models

This sample uses function calling capable models and has been tested with the following models:

| Model type | Model name/id | Model version | Supported |
| --------------- | ------------------------- | ------------------: | --------- |
| Chat Completion | gpt-3.5-turbo | 0125 ||
| Chat Completion | gpt-3.5-turbo-1106 | 1106 ||
| Chat Completion | gpt-3.5-turbo-0613 | 0613 ||
| Chat Completion | gpt-3.5-turbo-0301 | 0301 ||
| Chat Completion | gpt-3.5-turbo-16k | 0613 ||
| Chat Completion | gpt-4 | 0613 ||
| Chat Completion | gpt-4-0613 | 0613 ||
| Chat Completion | gpt-4-0314 | 0314 ||
| Chat Completion | gpt-4-turbo | 2024-04-09 ||
| Chat Completion | gpt-4-turbo-2024-04-09 | 2024-04-09 ||
| Chat Completion | gpt-4-turbo-preview | 0125-preview ||
| Chat Completion | gpt-4-0125-preview | 0125-preview ||
| Chat Completion | gpt-4-vision-preview | 1106-vision-preview ||
| Chat Completion | gpt-4-1106-vision-preview | 1106-vision-preview ||

ℹ️ OpenAI Models older than 0613 version do not support function calling.

## Configuring the sample

The sample can be configured by using the command line with .NET [Secret Manager](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets) to avoid the risk of leaking secrets into the repository, branches and pull requests.

### Using .NET [Secret Manager](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets)

```powershell
# OpenAI
dotnet user-secrets set "OpenAI:ChatModelId" "gpt-3.5-turbo"
dotnet user-secrets set "OpenAI:ApiKey" "... your api key ... "
```

## Running the sample

After configuring the sample, to build and run the console application just hit `F5`.

To build and run the console application from the terminal use the following commands:

```powershell
dotnet build
dotnet run
```

### Example of a conversation

Ask questions to use the Time Plugin such as:
- What time is it?

**User** > What time is it ?

**Assistant** > The current time is Sun, 12 May 2024 15:53:54 GMT.

23 changes: 23 additions & 0 deletions dotnet/samples/Demos/TimePlugin/TimePlugin.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>5ee045b0-aea3-4f08-8d31-32d1a6f8fed0</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Connectors\Connectors.OpenAI\Connectors.OpenAI.csproj" />
<ProjectReference Include="..\..\..\src\SemanticKernel.Abstractions\SemanticKernel.Abstractions.csproj" />
<ProjectReference Include="..\..\..\src\SemanticKernel.Core\SemanticKernel.Core.csproj" />
</ItemGroup>

</Project>

0 comments on commit 132693c

Please sign in to comment.