-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
.Net: API Manifest Plugins #4662
Conversation
* ApiManifest Plugin implementation & Example (#18)
Call ApiManifest Plugin via HandlebarsPlanner
Use JSON Compliant Copy of MsGraph OpenAPI Document
…lanner convert samples to use FunctionCallingStepwisePlanner
Convert APIManifest examples into test cases
add experimental flags for APIManifest features
parameterize test cases
dotnet/src/Functions/Functions.OpenApi/Extensions/OpenApiKernelExtensions.cs
Outdated
Show resolved
Hide resolved
dotnet/src/Functions/Functions.OpenApi/Extensions/OpenApiKernelExtensions.cs
Outdated
Show resolved
Hide resolved
dotnet/src/Functions/Functions.OpenApi/Extensions/OpenApiKernelExtensions.cs
Outdated
Show resolved
Hide resolved
dotnet/src/Functions/Functions.OpenApi/Extensions/OpenApiKernelExtensions.cs
Outdated
Show resolved
Hide resolved
dotnet/src/Functions/Functions.OpenApi/Extensions/OpenApiKernelExtensions.cs
Outdated
Show resolved
Hide resolved
dotnet/src/Functions/Functions.OpenApi/Extensions/OpenApiKernelExtensions.cs
Outdated
Show resolved
Hide resolved
Address PR comments
kernel.LoggerFactory.CreateLogger(typeof(OpenApiKernelExtensions)) ?? NullLogger.Instance, | ||
httpClient, | ||
authCallback: null, | ||
HttpHeaderValues.UserAgent, |
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.
It should be possible to override the user agent if needed. See the example here -
semantic-kernel/dotnet/src/Functions/Functions.OpenApi/Extensions/OpenApiKernelExtensions.cs
Line 154 in e4874bb
executionParameters?.UserAgent, |
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.
The type name OpenApiFunctionExecutionParameters
suggests that these are parameters to be used while calling the plugin functions (i.e. executing them). For example, we can't use the authCallback override from execution parameters in the line above because it is intended for the REST API call, not for fetching the OpenAPI document. Wouldn't the parameters be overloaded if used at the time of import? If the intention is to use for both, please let me know.
dotnet/src/Functions/Functions.OpenApi/Extensions/OpenApiKernelExtensions.cs
Outdated
Show resolved
Hide resolved
dotnet/src/Functions/Functions.OpenApi/Extensions/OpenApiKernelExtensions.cs
Outdated
Show resolved
Hide resolved
@zengin Could you please describe the scenarios in which this API Manifest functionality will be used? |
…ases Remove planner dependency from API Manifest tests
Sure. The biggest advantage of using API Manifest over an entire OpenAPI document currently is when an API contains too many operations such as Microsoft Graph (thousands of operations), where you only need a slice of it as a plugin. Another developer's API may not be as big, but they may want to limit operations of the plugin to read-only endpoints (or any other subset criterion that makes sense). API Manifest also allows adding more than one OpenAPI reference, which a scenario specific plugin may require (e.g. read GitHub issues and add them as a task into the todo list). Given that API Manifest is under development and is more flexible in terms of the format, we will be able to add features required to describe a plugin, which may not necessarily be part of the OpenAPI specification. Additional decorations it contains are similar but not limited to OpenAI's plugin manifest or Microsoft Copilot's plugin manifest. Eventually OpenAPI spec may support all these additional decorations to power AI scenarios (as pointed out here), in that case, plugin manifests may be considered an interim solution, but at least in the short term, they are going to be around to complement what's missing in the OpenAPI spec to guide LLMs on how to consume the APIs. |
Co-authored-by: Peter Ombwa <peter.ombwa@microsoft.com>
Address PR comments
@zengin We are going to close this PR and move forward with a separate package for this functionality. |
### Motivation and Context - fixes #4851 ### Description Adds an empty project to host OpenAPI plugin extensions e.g. API Manifest plugins (related PR: #4662) ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [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 😄 --------- Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com> Co-authored-by: Mark Wallace <127216156+markwallace-microsoft@users.noreply.github.com>
### Motivation and Context - fixes microsoft#4851 ### Description Adds an empty project to host OpenAPI plugin extensions e.g. API Manifest plugins (related PR: microsoft#4662) ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [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 😄 --------- Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com> Co-authored-by: Mark Wallace <127216156+markwallace-microsoft@users.noreply.github.com>
### Motivation and Context This PR contains main implementation part of #4662 and adds it into `Functions.OpenApi.Extensions` project. There were also couple of bug fixes in the mentioned PR, those will be handled in subsequent PRs. API Manifest can describe capabilities of an AI plugin for a chat-based system among other things. For a full description of API Manifest, see the [API Manifest Specification](https://darrelmiller.github.io/api-manifest/draft-miller-api-manifest.html). API Manifest refers to one or more OpenAPI documents as API dependencies and it selects a subset of operations from those documents to describe the capabilities of an AI plugin. ### Description Semantic Kernel has a way of creating plugins from OpenAPI operations, but it has a couple of limitations that can be addressed with API Manifest: 1. It can only create functions from OpenAPI operations that are described in a single OpenAPI document. 2. It cannot reference multiple OpenAPI documents in a single plugin. Not being able to slice OpenAPI operations is a major limitation, especially for large APIs such as Microsoft Graph, which has over 1000 operations. Today, we can create a Semantic Kernel plugin from an OpenAPI file and one OpenAPI file corresponds to one plugin. We don't have a way of selecting a subset of operations. ```mermaid graph TB subgraph OpenAPI1 operation11 operation12 operation13 end subgraph OpenAPI2 operation21 operation22 operation23 end subgraph OpenAPIPlugin1 function11 function12 function13 end subgraph OpenAPIPlugin2 function21 function22 function23 end operation11 -.- function11 operation12 -.- function12 operation13 -.- function13 operation21 -.- function21 operation22 -.- function22 operation23 -.- function23 style OpenAPIPlugin1 fill:blue,color:white style OpenAPIPlugin2 fill:blue,color:white ``` ### Proposed Solution After Semantic Kernel APIManifest support, we will have an APIManifest file, which will be used as a filter on OpenAPI files and it can reference more than one OpenAPI file. The filter can be used as a guide to select only certain operations to be converted into functions. Assume that we want to create a single plugin with `function11` from `OpenAPI1` and `function21` and `function22` from `OpenAPI2`. We want to preserve the one-to-one mapping between the APIManifest and the plugin, e.g. between `ApiManifestX` and `PluginX`: ```mermaid graph TB subgraph OpenAPI1 operation11 operation12 operation13 end subgraph OpenAPI2 operation21 operation22 operation23 end subgraph APIManifestX reference11 reference21 reference22 end subgraph PluginX function11 function21 function22 end reference11 -.- operation11 reference21 -.- operation21 reference22 -.- operation22 function11 -.- reference11 function21 -.- reference21 function22 -.- reference22 style APIManifestX fill:green,color:white style PluginX fill:blue,color:white ``` If we use existing OpenAPI to Plugin public methods after on-the-fly slicing, we can only achieve the following because there is an assumption that a single OpenAPI is converted into a single plugin, which breaks APIManifest to Plugin one-to-one mapping. A single `APIManifestX` file corresponds to two plugins, namely, `PluginX1` and `PluginX2`: ```mermaid graph TB subgraph OpenAPI1 operation11 operation12 operation13 end subgraph OpenAPI2 operation21 operation22 operation23 end subgraph APIManifestX reference11 reference21 reference22 end subgraph OpenAPI1_Sliced operation11_sliced[operation11] end subgraph OpenAPI2_Sliced operation21_sliced[operation21] operation22_sliced[operation22] end subgraph PluginX1 function11 end subgraph PluginX2 function21 function22 end reference11 -.- operation11 reference21 -.- operation21 reference22 -.- operation22 operation11 -.- operation11_sliced -.- function11 operation21 -.- operation21_sliced -.- function21 operation22 -.- operation22_sliced -.- function22 style APIManifestX fill:green,color:white style PluginX1 fill:blue,color:white style PluginX2 fill:blue,color:white ``` To avoid this, the implementation of regular OpenAPI plugin generation and API Manifest plugin generation meets at the function generation level, so reuse starts at `CreateRestApiFunction`. The PR also adds a KernelSyntaxExample for `/me/messages` endpoint of Microsoft Graph. ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [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 😄 --------- Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
Motivation and Context
This PR adds a prototype implementation of API Manifest based plugins.
APIManifest spec is located here. API Manifest is a format that allows defining an AI plugin from an existing OpenAPI, by specifying which subset of request paths to use in addition to other requirements such as auth. This PR contains a basic prototype covering a subset of the spec. The rest of the evolving spec will be implemented with follow up PRs and they will be shaped by the feedback we get.
Description
This PR exposes two public kernel extensions
ImportPluginFromApiManifestAsync
andCreatePluginFromApiManifestAsync
which are similar in signature as their OpenAPI counterparts. They take APIManifest file location, read contents, slice referenced OpenAPI document based on what is described in therequests
section. They then use underlying SemanticKernel OpenAPI function generation logic to generate functions and return a plugin instance.These features are marked as experimental and give a compiler warning when used. We used
SKEXP0099
as the diagnostic ID to avoid collision. We would like to hear what the right way is to increment and assign these numbers.We also extended the function name generation logic to not rely on operationId as it is optional in OpenAPI spec. We should probably change the main Functions.OpenAPI implementation as well, but current implementation only proposes an override at the moment, where the name is generated from the path and method outside.
We also fixed a minor serialization bug where the depth was not enough to represent Graph API shape.
Lastly, we add Microsoft Graph samples in the KernelSyntaxExamples project. Same argument holds with the naming of `Example99``, i.e. to avoid collision with examples coming from other PRs.
Running the sample
In order to run the samples, you need an
appsettings.Development.json
file in KernelSyntaxExamples folder in this shape:Create an MSAL app registration in the Azure portal, and add the client id to the appsettings.Development.json file.
Run the following command and login with your test MSA account. The sample expects at least one email message in inbox, a
test.txt
file in the root OneDrive folder, and at least one event in the calendar.Expected output
Contribution Checklist