microsoft / semantic-kernel

Integrate cutting-edge LLM technology quickly and easily into your apps
https://aka.ms/semantic-kernel
MIT License
21.31k stars 3.13k forks source link

Can't find ImportChatGptPluginSkillFromUrlAsync on version 0.16 #1546

Closed adiazcan closed 1 year ago

adiazcan commented 1 year ago

I'm trying to import a ChatGPT custom plugin from swagger, but I can't find the ImportChatGptPluginSkillFromUrlAsync on the kernel.

I'm following the Example21_ChatGPTPlugins, with the latest nugget version of Microsoft.SemanticKernel, Version=0.16.230615.1-preview.

Did I miss anything on my code? I can't find this extension.

teresaqhoang commented 1 year ago

Hey, do you have using Microsoft.SemanticKernel; declared at the top of your file?

The ImportChatGptPluginSkillFromUrlAsync is declared in KernelChatGptPluginExtensions, so you have to add the Microsoft.SemanticKernel namespace before you can use it.

If that doesn't help, can you share what your file looks like, or at least snippets of how you're initializing the kernel and making the import call?

adiazcan commented 1 year ago

Hello @teresaqhoang

I have the following using:

using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Planning; using Microsoft.SemanticKernel.Planning.Sequential;

But I cannot find the extension method:

image

And i have the lastest version of the SK Nugget

image

teresaqhoang commented 1 year ago

@adiazcan The ChatGPT plugins import have a dependency on OpenAPI import -- can you add the following package and see if that resolves your issue?

<PackageReference Include="Microsoft.SemanticKernel.Skills.OpenAPI" Version="0.16.230615.1-preview" />

adiazcan commented 1 year ago

Great!! Thanks for your help, now I can continue testing my plugins.

image

teresaqhoang commented 1 year ago

Okay awesome! I'll close this issue now, feel free to reopen if you run into any other problems

adiazcan commented 1 year ago

@teresaqhoang I have an expection loading the plugin openapi specification, can you help me?

Just importing the ChatGPT plugin

using HttpClient importHttpClient = new(); await kernel.ImportChatGptPluginSkillFromUrlAsync("Customers", new Uri("http://localhost:5073/.well-known/ai-plugin.json"), importHttpClient);

I have the following exception:

Unhandled exception. System.InvalidOperationException: Sequence contains no elements at System.Linq.ThrowHelper.ThrowNoElementsException() at System.Linq.Enumerable.First[TSource](IEnumerable1 source) at Microsoft.SemanticKernel.Skills.OpenAPI.OpenApi.OpenApiDocumentParser.ExtractRestApiOperations(OpenApiDocument document) at Microsoft.SemanticKernel.Skills.OpenAPI.OpenApi.OpenApiDocumentParser.ParseAsync(Stream stream, CancellationToken cancellationToken) at Microsoft.SemanticKernel.KernelOpenApiExtensions.RegisterOpenApiSkillAsync(IKernel kernel, Stream documentStream, String skillName, AuthenticateRequestAsyncCallback authCallback, HttpRetryConfig retryConfiguration, String userAgent, Uri serverUrlOverride, CancellationToken cancellationToken) at Microsoft.SemanticKernel.KernelOpenApiExtensions.ImportOpenApiSkillFromUrlAsync(IKernel kernel, String skillName, Uri url, HttpClient httpClient, AuthenticateRequestAsyncCallback authCallback, String userAgent, HttpRetryConfig retryConfiguration, Uri serverUrlOverride, CancellationToken cancellationToken) at Microsoft.SemanticKernel.KernelChatGptPluginExtensions.ImportChatGptPluginSkillFromUrlAsync(IKernel kernel, String skillName, Uri url, HttpClient httpClient, AuthenticateRequestAsyncCallback authCallback, String userAgent, HttpRetryConfig retryConfiguration, CancellationToken cancellationToken) at Planner.EmailAllCustomersAsync(IKernel kernel) in C:\github\Semantic\src\Planner.cs:line 110 at Program.

$(String[] args) in C:\github\Semantic\src\Program.cs:line 79 at Program.
(String[] args)`

My openapi file looks like: { "openapi": "3.0.1", "info": { "title": "customers-api", "version": "1.0" }, "paths": { "/customers": { "get": { "tags": [ "customers-api" ], "description": "Get all customers", "operationId": "GetCustomers", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Customer" } } } } } } } } }, "components": { "schemas": { "Customer": { "type": "object", "properties": { "id": { "type": "integer", "format": "int32" }, "name": { "type": "string", "nullable": true } }, "additionalProperties": false } } } }

and this is the plugin manifest: { "schema_version": "v1", "name_for_human": "Customers", "name_for_model": "customers", "description_for_human": "Manage Customers list. You can add, remove and view your Customers.", "description_for_model": "Plugin for managing a Customers list, you can add, remove and view your Customers.", "auth": { "type": "none" }, "api": { "type": "openapi", "url": "http://localhost:5073/swagger/v1/swagger.json" }, "logo_url": "http://localhost:5003/logo.png", "contact_email": "legal@example.com", "legal_info_url": "http://example.com/legal" }

adiazcan commented 1 year ago

@teresaqhoang I just found the problem, my openapi specification doesn't have a Server section, so the ExtractRestApiOperations failed.

image

I don't know if this section is mandatory or it has to read the server property from the plugin manifest.

teresaqhoang commented 1 year ago

Hey @adiazcan, ack! We're able to import a Jira OpenAPI specification, which also doesn't have a servers section, so in theory, yours should work. I'll do some testing on my end and keep you updated

gitri-ms commented 1 year ago

Hey @adiazcan, I'm picking up this issue, let me see if I can help you out! Here is some additional info about the servers property in OpenAPI 3.0. Our code expects the this section to be there, but according to the docs, it doesn't have to be, and the server URL should default to / if it's not. So that's something I will fix on our end.

In the meantime, can you add this section to your openapi file and see if it works as you'd expect? That would confirm that this is indeed the right fix.

"servers": [
    {
      "url": "/",
    },
],
adiazcan commented 1 year ago

Thanks @gitri-ms, that's the behaviour I found debugging your code. I had to change my dotnet api to include the servers section on the swagger. By default, it doesn't include it.

gitri-ms commented 1 year ago

Just making the change I suggested above doesn't appear to be sufficient. It seems that we don't currently handle relative URLs at all, even though they are allowed by the OpenAPI spec.

@SergeyMenshykh can you take a look at this?

gitri-ms commented 1 year ago

@adiazcan I've followed up on this and found out that this is not actually a bug, but a scoping decision at the time the OpenAPI skill was added. For now, we require the server URL to be provided in the OpenAPI spec. There is also a workaround where you can set the server-url context variable before invoking the skill -- see an example of that here.

I am going to close this issue and open a new feature request to add support for empty or relative server URLs so that it can be triaged by our team. (If you feel motivated and want to submit a PR for it yourself, though, feel free!)