-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
OpenAPI skills MVP #188
Conversation
/// <summary> | ||
/// OpenApi skill provider. | ||
/// </summary> | ||
public static class LocalOpenApiSkillsProvider |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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"
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
dotnet/src/SemanticKernel.Skills/Skills.OpenAPI/Skills/LocalOpenApiSkillsProvider.cs
Outdated
Show resolved
Hide resolved
samples/dotnet/kernel-syntax-examples/Example16_OpenApiSkill.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
//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)) |
There was a problem hiding this comment.
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>"); |
There was a problem hiding this comment.
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.
dotnet/src/SemanticKernel.Skills/Skills.OpenAPI/Authentication/IAuthenticationHandler.cs
Show resolved
Hide resolved
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); |
There was a problem hiding this comment.
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"]); |
There was a problem hiding this comment.
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 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). |
### 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.
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:
Contribution Checklist
dotnet format