microsoft / semantic-kernel

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

.Net: ImportPluginFromOpenApiAsync fails with Neither of the media types of <OperationName> is supported. #4926

Open pedershk opened 8 months ago

pedershk commented 8 months ago

Describe the bug When attempting to import a plugin from an openapi manifest, the kernel.ImportPluginFromOpenApiAsync() method fails with a non-descriptive error message "ImportPluginFromOpenApiAsync fails with Neither of the media types of is supported."

To Reproduce Attempt to use ImportPluginFromOpenApiAsync against an endpoint exposing swagger.json as attached in issue

Expected behavior Successfully connecting to the plugin/endpoint, as it exposes a documented schema and content type application/json

Screenshots/Files swagger.json for endpoint/plugin in question is attached

Platform

swagger-geographicaldata.json

matthewbolanos commented 8 months ago

@SergeyMenshykh, adding you to this thread since it looks like an OpenApi issue. @pedershk is internal in Microsoft, so if you reach out to him, he can share more of what his code looks like.

pedershk commented 8 months ago

I managed to solve this.

For Minimal APIs to produce a valid OpenAPI spec where there is no specific request BODY (such as this GET request), The RequestBody parameter in WithOpenApi has to be set explicitly to null, or an invalid requestBody element is produced in the resulting OpenAPI spec.

This is the JSON element that produces the error (see the originally attached swagger.json)

"requestBody": {
       "content": {}
 },

Similar behavior under slightly different conditions has been flagged as a bug previously and was fixed according to this issue in the dotnet/aspnetcore repository, but it still occurs in this particular instance.

Ping @captainsafia for awareness.

The Minimal API in question is using Microsoft.AspNetCore.OpenApi v8.0.1.

Maybe Microsoft.SemanticKernel.Plugins.OpenApi should scan for such empty requestBody elements before doing validation, or ignore them.

Working code definition with RequestBodyexplicitly set to null:

app.MapGet("/getlatitudeandlongitudeforaddress/{query}", async (string query) =>
    {
        string? location = query;

        if (string.IsNullOrWhiteSpace(location))
        {
            throw new ArgumentException("Location must be provided");
        }

        return await this.GetLatLongForAddressAsync(location);
    })
    .WithName("GetLatitudeAndLongitudeForAddress")
    .WithOpenApi(x => new(x)

    {
        RequestBody = null,
        Description =
            "Gets the latitude and longitude for an address in a json document. Set the \"query\" parameter to the address. Never use this function when coordinates are supplied by user.",
        Parameters = new List<OpenApiParameter>()
        {
            new OpenApiParameter()
            {
                Name = "query",
                Description =
                    "The query to submit to Azure maps. Must be an address consisting of street address, city and country. Ignore if input is only geographical coordinates",
                Required = true,
                In = ParameterLocation.Path,
            }
        }
    });
captainsafia commented 8 months ago

The Minimal API in question is using Microsoft.AspNetCore.OpenApi v8.0.1.

I'm a little surprised at this because the fix for this was applied in 8.0-preview4 and shoul've landed in these bits. It looks like the getlatitudeandlongitudeforaddress route in the API is causing the issue. I haven't been able to repro with an endpoint that has a similar shape. Is there a chance you are able to upload your repro?

github-actions[bot] commented 5 months ago

This issue is stale because it has been open for 90 days with no activity.