Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenAPI skills MVP #188

Merged

Conversation

SergeyMenshykh
Copy link
Member

Motivation and Context

The change lay foundation for OpenApi skills support by introducing a set of classes for importing, parsing OpenApi documents and sending HTTP requests to the resources described in them.

Description

The PR adds the following classes/methods:

  • ImportOpenApiFromDirectoryExtension – discovers OpenAPI document in a folder, creates SKFunction per REST operation in the document, and registers the functions in the Kernel.
  • RegisterOpenApiSkill - reates SKFunction per REST operation in the document, and registers the functions in the Kernel.
  • OpenApiDocumentParser – iterates over the collection of paths in OpenAPI document and creates an instance of RestOperation model class for each of them.
  • RestOperationRunner – accepts an instance of the RestOperation class and collection of arguments. Gets all required components (url, body, headers, …) for HTTP request and sends the request.
  • A few other model, exception, and helper classes.

Contribution Checklist

@SergeyMenshykh SergeyMenshykh added the PR: ready for review All feedback addressed, ready for reviews label Mar 28, 2023
/// <summary>
/// OpenApi skill provider.
/// </summary>
public static class LocalOpenApiSkillsProvider
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the skill/class named "Local*"? Couldn't this just be an OpenApiSkillProvider with LoadFromResource, LoadFromFilePath, LoadFromUrl...?
...or even better, just include these three types in the Kernel extensions.

/// <summary>
/// The Rest operation.
/// </summary>
internal class RestOperation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use of the term "Rest" across the PR is giving me a weird feeling. I'm not sure why; it's not invalid. Maybe it's because it's "Rest" and not "REST".
I think, before merging to main, we should have a quick naming conversation and apply it everywhere. Other options: "RestApiOperation", "WebApiOperation"

Copy link

@umeshma umeshma Mar 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameter types are already part of the Microsoft.OpenApi SDK. All defined here.
Microsoft.OpenApi.Models.ParameterLocation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will evaluate this change in a (near) future change.

/// </summary>
public static class KernelOpenApiExtensions
{
public static IDictionary<string, ISKFunction> RegisterOpenApiSkill(this IKernel kernel, Stream documentStream, string skillName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll want a overload of this that loads directly from a json url, and one from a local file json path (maybe these are the same... both string paths)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this review into the feature branch, I am okay leaving this to just the local and adding URL loading in a future change.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already a OpenApiParameter object.
Microsoft.OpenApi.Models.OpenApiParameter

Copy link
Contributor

@adrianwyatt adrianwyatt Mar 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SergeyMenshykh - Umesh has a good point. Though, to keep other work moving forward, I'm happy to bring this into the feature branch as-is if we look at replacing these models with Microsoft.OpenApi before merging to main. Unless you have other reasons to roll our own.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will evaluate this change in a (near) future change.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already a OpenApiOperation object.
Microsoft.OpenApi.Models.OpenApiOperation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will evaluate this change in a (near) future change.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why duplicate all the parameter information into internal objects?
I can see why you may want a REST operation, but why duplicate all the parameters and options? Just hold onto all the metadata types already defined in Microsoft.OpenAPI - keep a reference to them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will evaluate this change in a (near) future change.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where will retry etc. get applied for the HttpClient?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good callout. This is going into a feature branch for iteration and we'll be taking a look at robustness before merging into main.

@adrianwyatt adrianwyatt added PR: feedback to address Waiting for PR owner to address comments/questions and removed PR: ready for review All feedback addressed, ready for reviews labels Mar 28, 2023
//Example of auth routing - adding auth info to the Http request message based on host name.
var host = requestMessage.RequestUri.Host;

if (host.Contains("dev-tests.vault.azure.net", StringComparison.InvariantCultureIgnoreCase))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this address? Could you add a quick comment if the intention is to have this replaced.


if (host.Contains("dev-tests.vault.azure.net", StringComparison.InvariantCultureIgnoreCase))
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "<token>");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add an all caps comment to never check a token into any branch of git, local or otherwise.

catch (Exception ex) when (!ex.IsCriticalException())
{
//Logging the exception and keep registering other Rest functions
kernel.Log.LogWarning(ex, "Something went wrong while rendering the Rest function. Function: {0}.{1}. Error: {2}", skillName, operation.Id, ex.Message);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not throw?

//Use OpenApi skill from Skills.OpenAPI package
kernel.RegisterOpenApiSkill(LocalOpenApiSkillsProvider.LoadFroResource(LocalOpenApiSkillsProvider.AzureKeyVault), LocalOpenApiSkillsProvider.AzureKeyVault);

var plan = await kernel.RunAsync("Load 'test-secret' from Azure KeyValut available at https://dev-tests.vault.azure.net using GetSecret function.", planner["CreatePlan"]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future I would recommend not using the planner for this particular example, so as to keep the concept count limited to what we are trying to show.

@SergeyMenshykh SergeyMenshykh added the PR: ready for review All feedback addressed, ready for reviews label Mar 28, 2023
@adrianwyatt adrianwyatt merged commit 813e59f into microsoft:feature-openapi Mar 28, 2023
@shawncal
Copy link
Member

@SergeyMenshykh and @adrianwyatt Now that this is in the feature branch (which is great!) I've un-resolved all the unresolved comments so that they can be addressed in a pre-merge PR. Please make sure to note them (or they'll likely all come up again when merging to main).

dehoward pushed a commit to lemillermicrosoft/semantic-kernel that referenced this pull request Jun 1, 2023
### Motivation and Context

The change lay foundation for OpenApi skills support by introducing a
set of classes for importing, parsing OpenApi documents and sending HTTP
requests to the resources described in them.

### Description

The PR adds the following classes/methods:
- ImportOpenApiFromDirectoryExtension – discovers OpenAPI document in a
folder, creates SKFunction per REST operation in the document, and
registers the functions in the Kernel.
- RegisterOpenApiSkill - reates SKFunction per REST operation in the
document, and registers the functions in the Kernel.
- OpenApiDocumentParser – iterates over the collection of paths in
OpenAPI document and creates an instance of RestOperation model class
for each of them.
- RestOperationRunner – accepts an instance of the RestOperation class
and collection of arguments. Gets all required components (url, body,
headers, …) for HTTP request and sends the request.
- A few other model, exception, and helper classes.
Bryan-Roe added a commit to BMR-Cloud-Dev/semantic that referenced this pull request Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: feedback to address Waiting for PR owner to address comments/questions PR: ready for review All feedback addressed, ready for reviews
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants