Repository: microsoft/kiota (csharp)

Issue:
Ensure generated OpenAPI specs with no 200 response body comply with the OpenAPI spec
### Is your feature request related to a problem? Please describe the problem.

  ```yaml
/pet/{petId}:    
    delete:
      operationId: deletePet
      parameters:
        - name: api_key
          in: header
          description: ''
          required: false
          schema:
            type: string
      responses:
        '400':
          description: Invalid pet value
 ```

Then generated response is as below, with response is {}, this is not valid in standard OpenAPI spec file, maybe we should keep '400' response in generated spec file:
```yaml
  '/pet/{petId}':
    delete:
      summary: Deletes a pet
      description: delete a pet
      operationId: deletePet
      parameters:
        - name: api_key
          in: header
          description: ''
          schema:
            type: string
      responses: { }
```

Sample OpenAPI spec file:
https://github.com/SLdragon/example-openapi-spec/blob/main/petstore-official.yaml

### Client library/SDK language

None

### Describe the solution you'd like

Support responses without 200

### Additional context

![Image](https://github.com/user-attachments/assets/16069f36-ab8c-4576-997c-59d4d49047c0)

Pull request:
### Overview
Closes #6474 
The generated OpenAPI specs with no response were not compatible with Copilot. This PR adds a default 200 response for paths that do not have one.

### Demo
```yaml

openapi: 3.0.4
info:
  title: test - Subset
  version: '1.0'
servers:
  - url: http://localhost/
    description: There's no place like home
paths:
  /test:
    get:
      description: description for test path
      operationId: test_get
      responses:
        '200':
          description: The request has succeeded.
          content:
            text/plain:
              schema:
                type: string
components: { }

```

Patch:
diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs
index 7319201cbf..1a3139e9d9 100644
--- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs
+++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs
@@ -68,6 +68,8 @@ public async Task GenerateManifestAsync(CancellationToken cancellationToken = de
         // trimming a second time to remove any components that are no longer used after the inlining
         trimmedPluginDocument = GetDocumentWithTrimmedComponentsAndResponses(trimmedPluginDocument);
         trimmedPluginDocument.Info.Title = trimmedPluginDocument.Info.Title?[..^9]; // removing the second ` - Subset` suffix from the title
+
+        trimmedPluginDocument = GetDocumentWithDefaultResponses(trimmedPluginDocument);
         // Ensure reference_id extension value is written according to the plugin auth
         EnsureSecuritySchemeExtensions(trimmedPluginDocument);
         trimmedPluginDocument.SerializeAsV3(descriptionWriter);
@@ -416,6 +418,37 @@ private OpenApiDocument GetDocumentWithTrimmedComponentsAndResponses(OpenApiDocu
         return OpenApiFilterService.CreateFilteredDocument(doc, predicate);
     }
 
+    private static OpenApiDocument GetDocumentWithDefaultResponses(OpenApiDocument document)
+    {
+        if (document.Paths is null || document.Paths.Count == 0) return document;
+
+        foreach (var path in document.Paths)
+        {
+            if (path.Value.Operations is null) continue;
+
+            foreach (var operation in path.Value.Operations)
+            {
+                operation.Value.Responses ??= new OpenApiResponses();
+
+                if (operation.Value.Responses.Count == 0)
+                {
+                    operation.Value.Responses["200"] = new OpenApiResponse
+                    {
+                        Description = "The request has succeeded.",
+                        Content = new Dictionary<string, OpenApiMediaType>
+                        {
+                            ["text/plain"] = new OpenApiMediaType
+                            {
+                                Schema = new OpenApiSchema { Type = JsonSchemaType.String }
+                            }
+                        }
+                    };
+                }
+            }
+        }
+        return document;
+    }
+
     private PluginManifestDocument GetManifestDocument(string openApiDocumentPath)
     {
         var (runtimes, functions, conversationStarters) = GetRuntimesFunctionsAndConversationStartersFromTree(OAIDocument, Configuration, TreeNode, openApiDocumentPath, Logger);
@@ -764,7 +797,8 @@ rExtRaw is T rExt &&
             || response is null
             || response.Content is null
             || response.Content.Count == 0
-            || response.Content["application/json"]?.Schema is null)
+            || !response.Content.TryGetValue("application/json", out var mediaType)
+            || mediaType.Schema is null)
         {
             return null;
         }


Test patch:
diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs
index 12666d8fb7..2f93be39b0 100644
--- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs
+++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs
@@ -525,6 +525,64 @@ public async Task GeneratesManifestWithAdaptiveCardWithoutExtensionAsync()
 
     }
 
+    [Fact]
+    public async Task GeneratesManifestWithDefault200ResponseAsync()
+    {
+        var simpleDescriptionContent = @"openapi: 3.0.0
+info:
+  title: test
+  version: 1.0
+servers:
+  - url: http://localhost/
+    description: There's no place like home
+paths:
+  /test:
+    get:
+      description: description for test path
+      externalDocs:
+        description: external docs for test path
+        url: http://localhost/test
+      responses:
+        '400':
+          description: client error response
+";
+
+        var workingDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
+        var simpleDescriptionPath = Path.Combine(workingDirectory) + "description.yaml";
+        await File.WriteAllTextAsync(simpleDescriptionPath, simpleDescriptionContent);
+        var openAPIDocumentDS = new OpenApiDocumentDownloadService(_httpClient, _logger);
+        var outputDirectory = Path.Combine(workingDirectory, "output");
+        var generationConfiguration = new GenerationConfiguration
+        {
+            OutputPath = outputDirectory,
+            OpenAPIFilePath = simpleDescriptionPath,
+            PluginTypes = [PluginType.APIPlugin],
+            ClientClassName = "client",
+            ApiRootUrl = "http://localhost/", //Kiota builder would set this for us
+        };
+        var (openAPIDocumentStream, _) = await openAPIDocumentDS.LoadStreamAsync(simpleDescriptionPath, generationConfiguration, null, false);
+        var openApiDocument = await openAPIDocumentDS.GetDocumentFromStreamAsync(openAPIDocumentStream, generationConfiguration);
+        KiotaBuilder.CleanupOperationIdForPlugins(openApiDocument);
+        var urlTreeNode = OpenApiUrlTreeNode.Create(openApiDocument, Constants.DefaultOpenApiLabel);
+
+        var pluginsGenerationService = new PluginsGenerationService(openApiDocument, urlTreeNode, generationConfiguration, workingDirectory, _logger);
+        await pluginsGenerationService.GenerateManifestAsync();
+
+        Assert.True(File.Exists(Path.Combine(outputDirectory, ManifestFileName)));
+        Assert.True(File.Exists(Path.Combine(outputDirectory, OpenApiFileName)));
+
+        // Validate the v2 plugin
+        var manifestContent = await File.ReadAllTextAsync(Path.Combine(outputDirectory, ManifestFileName));
+
+        var (openAPIDocumentStream2, _) = await openAPIDocumentDS.LoadStreamAsync(Path.Combine(outputDirectory, OpenApiFileName), generationConfiguration, null, false);
+        var resultingSpec = await openAPIDocumentDS.GetDocumentFromStreamAsync(openAPIDocumentStream2, generationConfiguration);
+
+        using var jsonDocument = JsonDocument.Parse(manifestContent);
+        var resultingManifest = PluginManifestDocument.Load(jsonDocument.RootElement);
+        Assert.NotNull(resultingManifest.Document);
+        Assert.Single(resultingSpec.Paths["/test"].Operations[HttpMethod.Get].Responses);
+    }
+
 
     #region Security