Skip to content

Commit

Permalink
.Net: Rename ImportAIPluginAsync Update plugin import method and plan…
Browse files Browse the repository at this point in the history
…ner, and rename AIPlugin to Plugin in KernelAIPluginExtensions.cs (#2968)

### Contribution Checklist

- [x] The code builds clean without any errors or warnings
- [x] 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
- [x] All unit tests pass, and I have added new tests where possible
- [x] I didn't break anyone 😄

## Summary
This pull request includes three changes. First, the plugin import
method in the PluginTests.cs file of the IntegrationTests project has
been updated to use the ImportPluginFunctionsAsync method instead of the
deprecated ImportAIPluginAsync method. Second, the
StepwisePlannerTests.cs file in the same project has been updated to use
the Planning.StepwisePlanner method instead of the deprecated
Planning.StepwisePlannerAsync method. Finally, the
KernelAIPluginExtensions.cs file has been updated to rename all
instances of AIPlugin to Plugin, including renaming the
ImportAIPluginAsync method to ImportPluginFunctionsAsync. The changes
also include an obsolete attribute for the old method name, which will
be removed in a future release, and a new EditorBrowsable attribute to
hide the obsolete method from IntelliSense.

## Changes
- Replace ImportAIPluginAsync with ImportPluginFunctionsAsync in
PluginTests.cs
- Update StepwisePlannerTests.cs to use Planning.StepwisePlanner instead
of Planning.StepwisePlannerAsync
- Rename all instances of AIPlugin to Plugin in
KernelAIPluginExtensions.cs
- Rename ImportAIPluginAsync method to ImportPluginFunctionsAsync
- Add obsolete attribute to ImportAIPluginAsync method
- Add EditorBrowsable attribute to obsolete method

---
*Powered by [Microsoft Semantic
Kernel](https://github.com/microsoft/semantic-kernel)*
  • Loading branch information
markwallace-microsoft committed Sep 26, 2023
1 parent 13227dc commit 76db027
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 23 deletions.
Expand Up @@ -30,7 +30,7 @@ Chosen option: "Enable the dynamic creation of payload and/or namespacing based
In order to enable the dynamic creation of payloads/bodies for PUT and POST RestAPI operations, please set the `EnableDynamicPayload` property of the `OpenApiSkillExecutionParameters` execution parameters to `true` when importing the AI plugin:

```csharp
var plugin = await kernel.ImportAIPluginAsync("<skill name>", new Uri("<chatGPT-plugin>"), new OpenApiSkillExecutionParameters(httpClient) { EnableDynamicPayload = true });
var plugin = await kernel.ImportPluginFunctionsAsync("<skill name>", new Uri("<chatGPT-plugin>"), new OpenApiSkillExecutionParameters(httpClient) { EnableDynamicPayload = true });
```

To dynamically construct a payload for a RestAPI operation that requires payload like this:
Expand All @@ -55,7 +55,7 @@ contextVariables.Set("enabled", true);
To enable namespacing, set the `EnablePayloadNamespacing` property of the `OpenApiSkillExecutionParameters` execution parameters to `true` when importing the AI plugin:

```csharp
var plugin = await kernel.ImportAIPluginAsync("<skill name>", new Uri("<chatGPT-plugin>"), new OpenApiSkillExecutionParameters(httpClient) { EnablePayloadNamespacing = true });
var plugin = await kernel.ImportPluginFunctionsAsync("<skill name>", new Uri("<chatGPT-plugin>"), new OpenApiSkillExecutionParameters(httpClient) { EnablePayloadNamespacing = true });
```
Remember that the namespacing mechanism depends on prefixing parameter names with their parent parameter name, separated by dots. So, use the 'namespaced' parameter names when adding arguments for them to the context variables. Let's consider this JSON:

Expand Down
Expand Up @@ -22,7 +22,7 @@ private static async Task RunChatGptPluginAsync()
using HttpClient httpClient = new();

//Import a ChatGPT plugin via URI
var plugin = await kernel.ImportAIPluginAsync("<plugin name>", new Uri("<chatGPT-plugin>"), new OpenApiFunctionExecutionParameters(httpClient) { EnableDynamicPayload = true });
var plugin = await kernel.ImportPluginFunctionsAsync("<plugin name>", new Uri("<chatGPT-plugin>"), new OpenApiFunctionExecutionParameters(httpClient) { EnableDynamicPayload = true });

//Add arguments for required parameters, arguments for optional ones can be skipped.
var contextVariables = new ContextVariables();
Expand All @@ -38,7 +38,7 @@ private static async Task RunChatGptPluginAsync()

//var kernel = new KernelBuilder().WithLogger(ConsoleLogger.LoggerFactory).Build();

//var plugin = await kernel.ImportAIPluginAsync("Klarna", new Uri("https://www.klarna.com/.well-known/ai-plugin.json"), new OpenApiFunctionExecutionParameters(httpClient));
//var plugin = await kernel.ImportPluginFunctionsAsync("Klarna", new Uri("https://www.klarna.com/.well-known/ai-plugin.json"), new OpenApiFunctionExecutionParameters(httpClient));

//var contextVariables = new ContextVariables();
//contextVariables.Set("q", "Laptop"); // A precise query that matches one very small category or product that needs to be searched for to find the products the user is looking for. If the user explicitly stated what they want, use that as a query. The query is as specific as possible to the product name or category mentioned by the user in its singular form, and don't contain any clarifiers like latest, newest, cheapest, budget, premium, expensive or similar. The query is always taken from the latest topic, if there is a new topic a new query is started.
Expand Down
Expand Up @@ -46,7 +46,7 @@ public static async Task GetSecretFromAzureKeyVaultWithRetryAsync(InteractiveMsa
var stream = type.Assembly.GetManifestResourceStream(type, resourceName);

// Import AI Plugin
var plugin = await kernel.ImportAIPluginAsync(
var plugin = await kernel.ImportPluginFunctionsAsync(
PluginResourceNames.AzureKeyVault,
stream!,
new OpenApiFunctionExecutionParameters { AuthCallback = authenticationProvider.AuthenticateRequestAsync });
Expand All @@ -73,7 +73,7 @@ public static async Task AddSecretToAzureKeyVaultAsync(InteractiveMsalAuthentica
var stream = type.Assembly.GetManifestResourceStream(type, resourceName);

// Import AI Plugin
var plugin = await kernel.ImportAIPluginAsync(
var plugin = await kernel.ImportPluginFunctionsAsync(
PluginResourceNames.AzureKeyVault,
stream!,
new OpenApiFunctionExecutionParameters { AuthCallback = authenticationProvider.AuthenticateRequestAsync });
Expand Down
Expand Up @@ -33,7 +33,7 @@ public static async Task<string> ListPullRequestsFromGitHubAsync(BearerAuthentic
{
var kernel = new KernelBuilder().WithLoggerFactory(ConsoleLogger.LoggerFactory).Build();

var plugin = await kernel.ImportAIPluginAsync(
var plugin = await kernel.ImportPluginFunctionsAsync(
"GitHubPlugin",
"../../../samples/apps/copilot-chat-app/webapi/Skills/OpenApiSkills/GitHubSkill/openapi.json",
new OpenApiFunctionExecutionParameters { AuthCallback = authenticationProvider.AuthenticateRequestAsync });
Expand Down Expand Up @@ -65,7 +65,7 @@ public static async Task GetPullRequestFromGitHubAsync(BearerAuthenticationProvi
{
var kernel = new KernelBuilder().WithLoggerFactory(ConsoleLogger.LoggerFactory).Build();

var plugin = await kernel.ImportAIPluginAsync(
var plugin = await kernel.ImportPluginFunctionsAsync(
"GitHubPlugin",
"../../../samples/apps/copilot-chat-app/webapi/Skills/OpenApiSkills/GitHubSkill/openapi.json",
new OpenApiFunctionExecutionParameters { AuthCallback = authenticationProvider.AuthenticateRequestAsync });
Expand Down
Expand Up @@ -43,12 +43,12 @@ public static async Task RunAsync()
if (useLocalFile)
{
var apiPluginFile = "./../../../Plugins/JiraPlugin/openapi.json";
jiraFunctions = await kernel.ImportAIPluginAsync("jiraPlugin", apiPluginFile, new OpenApiFunctionExecutionParameters(authCallback: tokenProvider.AuthenticateRequestAsync));
jiraFunctions = await kernel.ImportPluginFunctionsAsync("jiraPlugin", apiPluginFile, new OpenApiFunctionExecutionParameters(authCallback: tokenProvider.AuthenticateRequestAsync));
}
else
{
var apiPluginRawFileURL = new Uri("https://raw.githubusercontent.com/microsoft/PowerPlatformConnectors/dev/certified-connectors/JIRA/apiDefinition.swagger.json");
jiraFunctions = await kernel.ImportAIPluginAsync("jiraPlugin", apiPluginRawFileURL, new OpenApiFunctionExecutionParameters(httpClient, tokenProvider.AuthenticateRequestAsync));
jiraFunctions = await kernel.ImportPluginFunctionsAsync("jiraPlugin", apiPluginRawFileURL, new OpenApiFunctionExecutionParameters(httpClient, tokenProvider.AuthenticateRequestAsync));
}

// GetIssue Function
Expand Down
Expand Up @@ -2,6 +2,7 @@

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
Expand All @@ -26,6 +27,20 @@ namespace Microsoft.SemanticKernel.Functions.OpenAPI.Extensions;
/// </summary>
public static class KernelAIPluginExtensions
{
[Obsolete("Methods and classes which includes Skill in the name have been renamed to use Plugin. Use Kernel.ImportPluginFunctionsAsync instead. This will be removed in a future release.")]
[EditorBrowsable(EditorBrowsableState.Never)]
#pragma warning disable CS1591
public static async Task<IDictionary<string, ISKFunction>> ImportAIPluginAsync(
this IKernel kernel,
string pluginName,
string filePath,
OpenApiFunctionExecutionParameters? executionParameters = null,
CancellationToken cancellationToken = default)
{
return await kernel.ImportPluginFunctionsAsync(pluginName, filePath, executionParameters, cancellationToken).ConfigureAwait(false);
}
#pragma warning restore CS1591

/// <summary>
/// Imports an AI plugin that is exposed as an OpenAPI v3 endpoint or through OpenAI's ChatGPT format.
/// </summary>
Expand All @@ -35,7 +50,7 @@ public static class KernelAIPluginExtensions
/// <param name="executionParameters">Plugin execution parameters.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A collection of invocable functions</returns>
public static async Task<IDictionary<string, ISKFunction>> ImportAIPluginAsync(
public static async Task<IDictionary<string, ISKFunction>> ImportPluginFunctionsAsync(
this IKernel kernel,
string pluginName,
string filePath,
Expand Down Expand Up @@ -65,6 +80,20 @@ public static class KernelAIPluginExtensions
cancellationToken: cancellationToken).ConfigureAwait(false);
}

[Obsolete("Methods and classes which includes Skill in the name have been renamed to use Plugin. Use Kernel.ImportPluginFunctionsAsync instead. This will be removed in a future release.")]
[EditorBrowsable(EditorBrowsableState.Never)]
#pragma warning disable CS1591
public static async Task<IDictionary<string, ISKFunction>> ImportAIPluginAsync(
this IKernel kernel,
string pluginName,
Uri uri,
OpenApiFunctionExecutionParameters? executionParameters = null,
CancellationToken cancellationToken = default)
{
return await kernel.ImportPluginFunctionsAsync(pluginName, uri, executionParameters, cancellationToken).ConfigureAwait(false);
}
#pragma warning restore CS1591

/// <summary>
/// Imports an AI plugin that is exposed as an OpenAPI v3 endpoint or through OpenAI's ChatGPT format.
/// </summary>
Expand All @@ -74,7 +103,7 @@ public static class KernelAIPluginExtensions
/// <param name="executionParameters">Plugin execution parameters.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A collection of invocable functions</returns>
public static async Task<IDictionary<string, ISKFunction>> ImportAIPluginAsync(
public static async Task<IDictionary<string, ISKFunction>> ImportPluginFunctionsAsync(
this IKernel kernel,
string pluginName,
Uri uri,
Expand Down Expand Up @@ -114,7 +143,7 @@ public static class KernelAIPluginExtensions
/// <param name="executionParameters">Plugin execution parameters.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A collection of invocable functions</returns>
public static async Task<IDictionary<string, ISKFunction>> ImportAIPluginAsync(
public static async Task<IDictionary<string, ISKFunction>> ImportPluginFunctionsAsync(
this IKernel kernel,
string pluginName,
Stream stream,
Expand Down Expand Up @@ -153,7 +182,7 @@ public static class KernelAIPluginExtensions
if (TryParseAIPluginForUrl(pluginContents, out var openApiUrl))
{
return await kernel
.ImportAIPluginAsync(
.ImportPluginFunctionsAsync(
pluginName,
new Uri(openApiUrl),
executionParameters,
Expand Down
Expand Up @@ -48,7 +48,7 @@ public KernelAIPluginExtensionsTests()
public async Task ItCanIncludeOpenApiOperationParameterTypesIntoFunctionParametersViewAsync()
{
//Act
var plugin = await this._kernel.ImportAIPluginAsync("fakePlugin", this._openApiDocument);
var plugin = await this._kernel.ImportPluginFunctionsAsync("fakePlugin", this._openApiDocument);

//Assert
var setSecretFunction = plugin["SetSecret"];
Expand Down Expand Up @@ -93,7 +93,7 @@ public async Task ItUsesServerUrlOverrideIfProvidedAsync(bool removeServersPrope
var variables = this.GetFakeContextVariables();

// Act
var plugin = await this._kernel.ImportAIPluginAsync("fakePlugin", new Uri(DocumentUri), executionParameters);
var plugin = await this._kernel.ImportPluginFunctionsAsync("fakePlugin", new Uri(DocumentUri), executionParameters);
var setSecretFunction = plugin["SetSecret"];

messageHandlerStub.ResetResponse();
Expand Down Expand Up @@ -131,7 +131,7 @@ public async Task ItUsesServerUrlFromOpenApiDocumentAsync(string documentFileNam
var variables = this.GetFakeContextVariables();

// Act
var plugin = await this._kernel.ImportAIPluginAsync("fakePlugin", new Uri(DocumentUri), executionParameters);
var plugin = await this._kernel.ImportPluginFunctionsAsync("fakePlugin", new Uri(DocumentUri), executionParameters);
var setSecretFunction = plugin["SetSecret"];

messageHandlerStub.ResetResponse();
Expand Down Expand Up @@ -176,7 +176,7 @@ public async Task ItUsesOpenApiDocumentHostUrlWhenServerUrlIsNotProvidedAsync(st
var variables = this.GetFakeContextVariables();

// Act
var plugin = await this._kernel.ImportAIPluginAsync("fakePlugin", new Uri(documentUri), executionParameters);
var plugin = await this._kernel.ImportPluginFunctionsAsync("fakePlugin", new Uri(documentUri), executionParameters);
var setSecretFunction = plugin["SetSecret"];

messageHandlerStub.ResetResponse();
Expand Down
Expand Up @@ -123,7 +123,7 @@ public async Task ExecutePlanSucceedsWithAlmostTooManyFunctionsAsync()
// Arrange
IKernel kernel = this.InitializeKernel();

_ = await kernel.ImportAIPluginAsync("Klarna", new Uri("https://www.klarna.com/.well-known/ai-plugin.json"), new OpenApiFunctionExecutionParameters(enableDynamicOperationPayload: true));
_ = await kernel.ImportPluginFunctionsAsync("Klarna", new Uri("https://www.klarna.com/.well-known/ai-plugin.json"), new OpenApiFunctionExecutionParameters(enableDynamicOperationPayload: true));

var planner = new Microsoft.SemanticKernel.Planners.StepwisePlanner(kernel);

Expand Down
8 changes: 4 additions & 4 deletions dotnet/src/IntegrationTests/Plugins/PluginTests.cs
Expand Up @@ -27,7 +27,7 @@ public class PluginTests
var kernel = new KernelBuilder().Build();
using HttpClient httpClient = new();

var plugin = await kernel.ImportAIPluginAsync(
var plugin = await kernel.ImportPluginFunctionsAsync(
name,
new Uri(pluginEndpoint),
new OpenApiFunctionExecutionParameters(httpClient));
Expand Down Expand Up @@ -59,7 +59,7 @@ public class PluginTests
using HttpClient httpClient = new();

//note that this plugin is not compliant according to the underlying validator in SK
var plugin = await kernel.ImportAIPluginAsync(
var plugin = await kernel.ImportPluginFunctionsAsync(
name,
new Uri(pluginEndpoint),
new OpenApiFunctionExecutionParameters(httpClient) { IgnoreNonCompliantErrors = true });
Expand Down Expand Up @@ -90,7 +90,7 @@ public class PluginTests
using HttpClient httpClient = new();

//note that this plugin is not compliant according to the underlying validator in SK
var plugin = await kernel.ImportAIPluginAsync(
var plugin = await kernel.ImportPluginFunctionsAsync(
name,
stream,
new OpenApiFunctionExecutionParameters(httpClient) { IgnoreNonCompliantErrors = true });
Expand Down Expand Up @@ -120,7 +120,7 @@ public class PluginTests
using HttpClient httpClient = new();

//note that this plugin is not compliant according to the underlying validator in SK
var plugin = await kernel.ImportAIPluginAsync(
var plugin = await kernel.ImportPluginFunctionsAsync(
name,
pluginFilePath,
new OpenApiFunctionExecutionParameters(httpClient) { IgnoreNonCompliantErrors = true });
Expand Down

0 comments on commit 76db027

Please sign in to comment.