diff --git a/kiota.sln b/kiota.sln
index 0f9857aaac..2ec6ecf0ac 100644
--- a/kiota.sln
+++ b/kiota.sln
@@ -19,6 +19,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EAAC5CEA-33B
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KiotaGenerated", "src\Kiota.Generated\KiotaGenerated.csproj", "{01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginsManifest", "..\Microsoft.Plugins.Manifest\src\PluginsManifest\PluginsManifest.csproj", "{55D60842-09BB-4EA8-9DF6-4ED9D2B1AA05}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -49,6 +51,10 @@ Global
{01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {55D60842-09BB-4EA8-9DF6-4ED9D2B1AA05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {55D60842-09BB-4EA8-9DF6-4ED9D2B1AA05}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {55D60842-09BB-4EA8-9DF6-4ED9D2B1AA05}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {55D60842-09BB-4EA8-9DF6-4ED9D2B1AA05}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/Kiota.Builder/Kiota.Builder.csproj b/src/Kiota.Builder/Kiota.Builder.csproj
index 3f54277d82..c807dd39ac 100644
--- a/src/Kiota.Builder/Kiota.Builder.csproj
+++ b/src/Kiota.Builder/Kiota.Builder.csproj
@@ -47,7 +47,7 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -62,4 +62,7 @@
+
+
+
diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs
index ef638601fa..0b5c166811 100644
--- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs
+++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs
@@ -10,10 +10,12 @@
using Kiota.Builder.Extensions;
using Kiota.Builder.OpenApiExtensions;
using Microsoft.OpenApi.ApiManifest;
+using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Services;
using Microsoft.OpenApi.Writers;
using Microsoft.Plugins.Manifest;
+using ValidationRuleSet = Microsoft.OpenApi.Validations.ValidationRuleSet;
namespace Kiota.Builder.Plugins;
@@ -258,13 +260,29 @@ private OpenApiDocument GetDocumentWithTrimmedComponentsAndResponses(OpenApiDocu
private PluginManifestDocument GetManifestDocument(string openApiDocumentPath)
{
+ // Validate OpenAPI
+ var ruleSet = new ValidationRuleSet
+ {
+ Microsoft.Plugins.Manifest.OpenApiRules.OpenApiServerUrlRule.ServerUrlMustBeHttps,
+ Microsoft.Plugins.Manifest.OpenApiRules.OpenApiCombinedAuthFlowRule
+ .PathsCanOnlyHaveOneSecuritySchemePerOperation(OAIDocument.SecurityRequirements),
+ Microsoft.Plugins.Manifest.OpenApiRules.OpenApiRequestBodySchemaRule.RequestBodySchemaObjectsMustNeverBeNested,
+ Microsoft.Plugins.Manifest.OpenApiRules.OpenApiApiKeyBearerRule.ApiKeyNotSupportedOnlyBearerPlusHttp(OAIDocument.SecurityRequirements)
+ };
+ var errors = OAIDocument.Validate(ruleSet)?.ToArray();
+ if (errors != null && errors.Length != 0)
+ {
+ var message = string.Join(Environment.NewLine, errors.Select(e => $"{e.Pointer}: {e.Message}"));
+ throw new InvalidOperationException(message);
+ }
var (runtimes, functions, conversationStarters) = GetRuntimesFunctionsAndConversationStartersFromTree(OAIDocument, Configuration.PluginAuthInformation, TreeNode, openApiDocumentPath);
var descriptionForHuman = OAIDocument.Info?.Description is string d && !string.IsNullOrEmpty(d) ? d : $"Description for {OAIDocument.Info?.Title}";
var manifestInfo = ExtractInfoFromDocument(OAIDocument.Info);
+ const string schemaVersion = "v2.1";
var pluginManifestDocument = new PluginManifestDocument
{
Schema = "https://developer.microsoft.com/json-schemas/copilot/plugin/v2.1/schema.json",
- SchemaVersion = "v2.1",
+ SchemaVersion = schemaVersion,
NameForHuman = OAIDocument.Info?.Title.CleanupXMLString(),
DescriptionForHuman = descriptionForHuman,
DescriptionForModel = manifestInfo.DescriptionForModel ?? descriptionForHuman,
@@ -295,6 +313,7 @@ private PluginManifestDocument GetManifestDocument(string openApiDocumentPath)
})
.ToList()
};
+
return pluginManifestDocument;
}