Skip to content

Commit

Permalink
.Net: Rename 'Skills' -> 'Plugins' - Part 6 Updates to MsGraphSkillsE…
Browse files Browse the repository at this point in the history
…xample, OpenApiPluginsExample, and graph-api-skills projects (#2938)

### Motivation and Context

- Rename MsGraphSkillsExample
- Rename OpenApiSkillsExample

### 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 😄

## Summary
This pull request includes updates to three different projects. In the
MsGraphSkillsExample project, the name has been changed to
MsGraphPluginsExample to better reflect the nature of the project as a
set of plugins rather than skills. In the OpenApiPluginsExample project,
the OpenAPI skills have been renamed to OpenAPI plugins throughout the
project, and the GitHub plugin has been updated to use a new API key
configuration option.

## Changes
- Renamed MsGraphSkillsExample project to MsGraphPluginsExample
- Updated all relevant files and references to reflect the new project
name
- Changed references to 'skills' to 'plugins' in RepoFiles.cs
- Updated README.md to reflect the new project name and purpose
- Changed exception message in YourAppException.cs to reflect the new
project name
- Renamed AzureOpenAIConfiguration.cs, OpenAIConfiguration.cs,
Program.cs, and README.md to reflect the new project name and purpose
- Updated the OpenApiSkillsExample project to use the new GitHubPlugin
instead of the deprecated GitHubSkill.
- Renamed the 'openapi-skills' directory to 'OpenApiPluginsExample'.
- Updated the README.md file to reflect the changes and to use the term
'plugin' instead of 'skill'.
- Renamed the 'RequiredOnPropertyValueAttribute.cs' file to
'OpenApiPluginsExample'.
- Updated the 'appsettings.json' file to use the new GitHubPlugin
options.

---
*Powered by [Microsoft Semantic
Kernel](https://github.com/microsoft/semantic-kernel)*
  • Loading branch information
markwallace-microsoft authored Sep 22, 2023
1 parent 559d6f3 commit ef4c5a5
Show file tree
Hide file tree
Showing 22 changed files with 55 additions and 54 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ FodyWeavers.xsd
.env
certs/
launchSettings.json
!samples/dotnet/MsGraphPluginsExample/Properties/launchSettings.json
config.development.yaml
*.development.config
*.development.json
Expand Down
4 changes: 2 additions & 2 deletions dotnet/SK-dotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{FA37
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KernelSyntaxExamples", "samples\KernelSyntaxExamples\KernelSyntaxExamples.csproj", "{47C6F821-5103-431F-B3B8-A2868A68BB78}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MsGraphSkillsExample", "..\samples\dotnet\graph-api-skills\MsGraphSkillsExample.csproj", "{3EB61E99-C39B-4620-9482-F8DA18E48525}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MsGraphPluginsExample", "..\samples\dotnet\MsGraphPluginsExample\MsGraphPluginsExample.csproj", "{3EB61E99-C39B-4620-9482-F8DA18E48525}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KernelHttpServer", "..\samples\dotnet\KernelHttpServer\KernelHttpServer.csproj", "{34A7F1EF-D243-4160-A413-D713FEABCD94}"
EndProject
Expand Down Expand Up @@ -93,7 +93,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "InternalUtilities", "Intern
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Connectors.Memory.Weaviate", "src\Connectors\Connectors.Memory.Weaviate\Connectors.Memory.Weaviate.csproj", "{6AAB0620-33A1-4A98-A63B-6560B9BA47A4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenApiSkillsExample", "..\samples\dotnet\openapi-skills\OpenApiSkillsExample.csproj", "{4D91A3E0-C404-495B-AD4A-411C4E83CF54}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenApiPluginsExample", "..\samples\dotnet\OpenApiPluginsExample\OpenApiPluginsExample.csproj", "{4D91A3E0-C404-495B-AD4A-411C4E83CF54}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Connectors.Memory.DuckDB", "src\Connectors\Connectors.Memory.DuckDB\Connectors.Memory.DuckDB.csproj", "{50FAE231-6F24-4779-9D02-12ABBC9A49E2}"
EndProject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using System.Diagnostics.CodeAnalysis;

namespace MsGraphSkillsExample;
namespace MsGraphPluginsExample;

[SuppressMessage("Performance", "CA1812:class never instantiated", Justification = "Instantiated through IConfiguration")]
internal sealed class AzureOpenAIConfiguration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using System.Diagnostics.CodeAnalysis;

namespace MsGraphSkillsExample;
namespace MsGraphPluginsExample;

[SuppressMessage("Performance", "CA1812:Internal class that is apparently never instantiated",
Justification = "Configuration classes are instantiated through IConfiguration.")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
using Microsoft.SemanticKernel.Skills.MsGraph.Connectors.CredentialManagers;
using DayOfWeek = System.DayOfWeek;

namespace MsGraphSkillsExample;
namespace MsGraphPluginsExample;

/// <summary>
/// The static plan below is meant to emulate a plan generated from the following request:
Expand Down Expand Up @@ -143,7 +143,7 @@ public static async Task Main()
var todo = sk.ImportSkill(todoSkill, "todo");
var outlook = sk.ImportSkill(outlookSkill, "outlook");

string skillParentDirectory = RepoFiles.SampleSkillsPath();
string skillParentDirectory = RepoFiles.SamplePluginsPath();

IDictionary<string, ISKFunction> summarizeSkills =
sk.ImportSemanticSkillFromDirectory(skillParentDirectory, "SummarizeSkill");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"GraphSkillsTestApp": {
"commandName": "Project",
"environmentVariables": {
"GraphSkillsTestApp_ClientId": "1234"
"GraphSkillsTestApp_ClientId": "12345"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Graph API Skill Example
# Graph API Plugin Example

This example program demonstrates how to use the Microsoft Graph API skills with the Semantic Kernel.
This example program demonstrates how to use the Microsoft Graph API plugins with the Semantic Kernel.

## Setup

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
using System.IO;
using System.Reflection;

namespace MsGraphSkillsExample;
namespace MsGraphPluginsExample;

public static class RepoFiles
{
/// <summary>
/// Scan the local folders from the repo, looking for "samples/skills" folder.
/// Scan the local folders from the repo, looking for "samples/plugins" folder.
/// </summary>
/// <returns>The full path to samples/skills</returns>
public static string SampleSkillsPath()
/// <returns>The full path to samples/plugins</returns>
public static string SamplePluginsPath()
{
const string Parent = "samples";
const string Folder = "skills";
const string Folder = "plugins";

bool SearchPath(string pathToFind, out string result, int maxAttempts = 10)
{
Expand All @@ -33,7 +33,7 @@ bool SearchPath(string pathToFind, out string result, int maxAttempts = 10)
if (!SearchPath(Parent + Path.DirectorySeparatorChar + Folder, out string path)
&& !SearchPath(Folder, out path))
{
throw new YourAppException("Skills directory not found. The app needs the skills from the repo to work.");
throw new YourAppException("Plugins directory not found. The app needs the plugins from the repo to work.");
}

return path;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using System;

namespace MsGraphSkillsExample;
namespace MsGraphPluginsExample;

public class YourAppException : Exception
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using System.ComponentModel.DataAnnotations;

namespace OpenApiSkillsExample;
namespace OpenApiPluginsExample;

/// <summary>
/// Configuration options for AI services, such as Azure OpenAI and OpenAI.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System;
using System.Text.Json.Serialization;

namespace GitHubSkill.Model;
namespace GitHubPlugin.Model;

/// <summary>
/// Represents a GitHub Pull Request.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using System.Text.Json.Serialization;

namespace GitHubSkill.Model;
namespace GitHubPlugin.Model;

/// <summary>
/// Represents a user on GitHub.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

using System.ComponentModel.DataAnnotations;

namespace OpenApiSkillsExample;
namespace OpenApiPluginsExample;

/// <summary>
/// Configuration options for GitHub skill.
/// Configuration options for GitHub plugin.
/// </summary>
public sealed class GitHubSkillOptions
public sealed class GitHubPluginOptions
{
public const string PropertyName = "GitHubSkill";
public const string PropertyName = "GitHubPlugin";

/// <summary>
/// GitHub API key.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System;
using System.ComponentModel.DataAnnotations;

namespace OpenApiSkillsExample;
namespace OpenApiPluginsExample;

/// <summary>
/// If the string is set, it must not be empty or whitespace.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
</PropertyGroup>

<ItemGroup>
<None Remove="GitHubSkill\openapi.json" />
<None Remove="GitHubPlugin\openapi.json" />
</ItemGroup>

<ItemGroup>
<Content Include="GitHubSkill\openapi.json">
<Content Include="GitHubPlugin\openapi.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using GitHubSkill.Model;
using GitHubPlugin.Model;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
Expand All @@ -18,18 +18,18 @@
using Microsoft.SemanticKernel.Skills.OpenAPI.Authentication;
using Microsoft.SemanticKernel.Skills.OpenAPI.Extensions;

namespace OpenApiSkillsExample;
namespace OpenApiPluginsExample;

/// <summary>
/// The chat example below is meant to demonstrate the use of an OpenAPI-based skill (e.g., GitHub),
/// The chat example below is meant to demonstrate the use of an OpenAPI-based plugin (e.g., GitHub),
/// a planner (e.g., ActionPlanner) and chat completions to create a conversational experience with
/// additional information from a skill when needed.
/// additional information from a plugin when needed.
/// </summary>
internal sealed class Program
{
private static async Task Main(string[] args)
{
Console.WriteLine("Welcome to Semantic Kernel OpenAPI Skills Example!");
Console.WriteLine("Welcome to Semantic Kernel OpenAPI Plugins Example!");

// Load configuration
IConfigurationRoot configuration = new ConfigurationBuilder()
Expand Down Expand Up @@ -68,18 +68,18 @@ private static async Task Main(string[] args)

var kernel = kb.Build();

// Register the GitHub skill using an OpenAPI definition containing only pull request GET operations.
GitHubSkillOptions gitHubOptions = configuration.GetRequiredSection(GitHubSkillOptions.PropertyName).Get<GitHubSkillOptions>()
?? throw new InvalidOperationException($"Missing configuration for {GitHubSkillOptions.PropertyName}.");
// Register the GitHub plugin using an OpenAPI definition containing only pull request GET operations.
GitHubPluginOptions gitHubOptions = configuration.GetRequiredSection(GitHubPluginOptions.PropertyName).Get<GitHubPluginOptions>()
?? throw new InvalidOperationException($"Missing configuration for {GitHubPluginOptions.PropertyName}.");

BearerAuthenticationProvider authenticationProvider = new(() => Task.FromResult(gitHubOptions.Key));

await kernel.ImportAIPluginAsync(
skillName: "GitHubSkill",
filePath: Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "GitHubSkill/openapi.json"),
skillName: "GitHubPlugin",
filePath: Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "GitHubPlugin/openapi.json"),
new OpenApiSkillExecutionParameters(authCallback: authenticationProvider.AuthenticateRequestAsync));

// Use a planner to decide when to call the GitHub skill. Since we are not chaining operations, use
// Use a planner to decide when to call the GitHub plugin. Since we are not chaining operations, use
// the ActionPlanner which is a simplified planner that will always return a 0 or 1 step plan.
ActionPlanner planner = new(kernel, logger: logger);

Expand All @@ -99,7 +99,7 @@ await kernel.ImportAIPluginAsync(

// Add GitHub's response, if any, to the chat history.
int planResultTokenAllowance = (int)(aiOptions.TokenLimit * 0.25); // Allow up to 25% of our token limit to be from GitHub.
string planResult = await PlanGitHubSkillAsync(gitHubOptions, planner, chatHistory, input, planResultTokenAllowance, logger);
string planResult = await PlanGitHubPluginAsync(gitHubOptions, planner, chatHistory, input, planResultTokenAllowance, logger);
if (!string.IsNullOrWhiteSpace(planResult))
{
chatHistory.AddUserMessage(planResult);
Expand Down Expand Up @@ -128,15 +128,15 @@ await kernel.ImportAIPluginAsync(
}

/// <summary>
/// Run the planner to decide whether to run the GitHub skill function and add the result to the chat history.
/// Run the planner to decide whether to run the GitHub plugin function and add the result to the chat history.
/// </summary>
private static async Task<string> PlanGitHubSkillAsync(
GitHubSkillOptions gitHubOptions, ActionPlanner planner, OpenAIChatHistory chatHistory, string input, int tokenAllowance, ILogger logger)
private static async Task<string> PlanGitHubPluginAsync(
GitHubPluginOptions gitHubOptions, ActionPlanner planner, OpenAIChatHistory chatHistory, string input, int tokenAllowance, ILogger logger)
{
// Ask the planner to create a plan based off the user's input. If the plan elicits no steps, continue normally.
Plan plan = await planner.CreatePlanAsync(input);

// Make sure the plan's state has the GitHub skill configuration values.
// Make sure the plan's state has the GitHub plugin configuration values.
plan.State.Set("repo", gitHubOptions.Repository);
plan.State.Set("owner", gitHubOptions.Owner);

Expand Down Expand Up @@ -192,13 +192,13 @@ private static string OptimizeGitHubPullRequestResponse(string planResult, int t
}

/// <summary>
/// Try to extract json from the planner response as if it were from an OpenAPI skill.
/// Try to extract json from the planner response as if it were from an OpenAPI plugin.
/// </summary>
private static bool TryExtractJsonFromOpenApiPlanResult(string openApiSkillResponse, ILogger logger, out string json)
private static bool TryExtractJsonFromOpenApiPlanResult(string openApiPluginResponse, ILogger logger, out string json)
{
try
{
JsonNode? jsonNode = JsonNode.Parse(openApiSkillResponse);
JsonNode? jsonNode = JsonNode.Parse(openApiPluginResponse);
string contentType = jsonNode?["contentType"]?.ToString() ?? string.Empty;
if (contentType.StartsWith("application/json", StringComparison.InvariantCultureIgnoreCase))
{
Expand All @@ -212,7 +212,7 @@ private static bool TryExtractJsonFromOpenApiPlanResult(string openApiSkillRespo
}
catch (JsonException)
{
logger.LogWarning("Unable to extract JSON from planner response, it is likely not from an OpenAPI skill.");
logger.LogWarning("Unable to extract JSON from planner response, it is likely not from an OpenAPI plugin.");
}
catch (InvalidOperationException)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Open API Skills Example
The chat example below is meant to demonstrate the use of an OpenAPI-based skill (e.g., GitHub), a planner (e.g., ActionPlanner)
and chat completions to create a conversational experience with additional information from a skill when needed.
# Open API Plugins Example
The chat example below is meant to demonstrate the use of an OpenAPI-based plugin (e.g., GitHub), a planner (e.g., ActionPlanner)
and chat completions to create a conversational experience with additional information from a plugin when needed.

The specific GitHub OpenAPI used is a reduced definition supporting viewing of pull requests.
The specific GitHub OpenAPI used is a reduced definition supporting viewing of pull requests.

## Preparing your environment
Before you get started, make sure you have the following requirements in place:
Expand All @@ -13,10 +13,10 @@ Before you get started, make sure you have the following requirements in place:
1. Clone the repository
2. Open the `./appsettings.json` and configure your AI service and GitHub credentials.
3. Run the sample
- In Visual Studio 2019 or newer, right-click on the `OpenApiSkillsExample` project, select "Set as Startup Project", then press `F5` to run and debug the application
- OR open a terminal window, change directory to the `OpenApiSkillsExample` project, then run `dotnet run`.
- In Visual Studio 2019 or newer, right-click on the `OpenApiPluginsExample` project, select "Set as Startup Project", then press `F5` to run and debug the application
- OR open a terminal window, change directory to the `OpenApiPluginsExample` project, then run `dotnet run`.

## Using the sample
The sample will provide a simple chat interface the large language model (e.g., gpt-3.5-turbo) and the planner will invoke the GitHub skill when needed.
The sample will provide a simple chat interface the large language model (e.g., gpt-3.5-turbo) and the planner will invoke the GitHub plugin when needed.

When asking for results from GitHub, try using bounded asks such as "List the three most recent open pull requests and include the name, number, and state for each."
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.ComponentModel.DataAnnotations;
using System.Reflection;

namespace OpenApiSkillsExample;
namespace OpenApiPluginsExample;

/// <summary>
/// If the other property is set to the expected value, then this property is required.
Expand Down

0 comments on commit ef4c5a5

Please sign in to comment.