Fix MEAI001 leak from experimental RequiresConfirmation in source-generated AIContent contexts - #7659
Merged
jeffhandley merged 1 commit intoJul 27, 2026
Conversation
…erated AIContent contexts
ToolApprovalRequestContent.RequiresConfirmation is [Experimental(MEAI001)] but the
type is a stable, statically-registered [JsonDerivedType] of the [JsonPolymorphic]
AIContent. System.Text.Json's source generator therefore emits the experimental member
into the JSON metadata of any consumer whose JsonSerializerContext includes AIContent
(e.g. List<AIContent>), forcing that consumer to suppress MEAI001 even when it never
uses approval APIs.
Route serialization through a non-experimental internal member: the public property is
now [JsonIgnore] and delegates to internal RequiresConfirmationCore, which carries
[JsonInclude] and [JsonPropertyName("requiresConfirmation")] so the value still
round-trips through the package's default serialization options. This mirrors the
existing pattern on UsageDetails token counts and HostedFileContent.
Also removes the now-unnecessary MEAI001 suppressions from the two Evaluation.Reporting
projects, which had gained them solely because of this leak (PR dotnet#7549).
Adds a no-suppression, MEAI001-as-error regression guard in the Stabilization tests: a
source-generated context over List<AIContent> that fails to compile if any experimental
member leaks back into consumer metadata.
Fixes dotnet#7658
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a regression where the experimental ToolApprovalRequestContent.RequiresConfirmation member leaked into consumers’ System.Text.Json source-generated AIContent contracts (triggering MEAI001) by gating serialization at the member level while preserving round-tripping through the library’s default serialization path.
Changes:
- Mark
RequiresConfirmationas[JsonIgnore]and route JSON through an internalRequiresConfirmationCoreproperty annotated with[JsonInclude]/[JsonPropertyName]. - Add a stabilization test
JsonSerializerContextrooted atList<AIContent>plus a runtime round-trip test to ensure the generated context is functional. - Remove now-unnecessary
MEAI001suppressions from the two Evaluation.Reporting projects.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| test/Libraries/Microsoft.Extensions.AI.Stabilization.Tests/AIContentSerializationRegressionTests.cs | Runtime round-trip test to validate the source-generated List<AIContent> context works. |
| test/Libraries/Microsoft.Extensions.AI.Stabilization.Tests/AIContentSerializationRegressionContext.cs | Compile-time guard context to prevent experimental-member leakage into consumer source generation. |
| src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Microsoft.Extensions.AI.Evaluation.Reporting.csproj | Removes MEAI001 suppression that was only needed due to the leak. |
| src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Azure/Microsoft.Extensions.AI.Evaluation.Reporting.Azure.csproj | Removes MEAI001 suppression that was only needed due to the leak. |
| src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/ToolApprovalRequestContent.cs | Implements the [JsonIgnore] + internal *Core serialization pattern to stop source-gen leakage while preserving default-option round-trip behavior. |
peterwald
approved these changes
Jul 27, 2026
jeffhandley
added a commit
that referenced
this pull request
Jul 27, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Jul 27, 2026
Closed
This was referenced Aug 13, 2026
GuillaumeBodson
pushed a commit
to GuillaumeBodson/Filer
that referenced
this pull request
Aug 13, 2026
Updated [Microsoft.AspNetCore.Authentication.JwtBearer](https://github.com/dotnet/dotnet) from 10.0.10 to 10.0.11. <details> <summary>Release notes</summary> _Sourced from [Microsoft.AspNetCore.Authentication.JwtBearer's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Updated [Microsoft.AspNetCore.Components.WebAssembly.DevServer](https://github.com/dotnet/dotnet) from 10.0.10 to 10.0.11. <details> <summary>Release notes</summary> _Sourced from [Microsoft.AspNetCore.Components.WebAssembly.DevServer's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Updated [Microsoft.AspNetCore.Identity.EntityFrameworkCore](https://github.com/dotnet/dotnet) from 10.0.10 to 10.0.11. <details> <summary>Release notes</summary> _Sourced from [Microsoft.AspNetCore.Identity.EntityFrameworkCore's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Updated [Microsoft.EntityFrameworkCore](https://github.com/dotnet/dotnet) from 10.0.10 to 10.0.11. <details> <summary>Release notes</summary> _Sourced from [Microsoft.EntityFrameworkCore's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Updated [Microsoft.EntityFrameworkCore.Design](https://github.com/dotnet/dotnet) from 10.0.10 to 10.0.11. <details> <summary>Release notes</summary> _Sourced from [Microsoft.EntityFrameworkCore.Design's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Updated [Microsoft.Extensions.DependencyInjection.Abstractions](https://github.com/dotnet/dotnet) from 10.0.10 to 10.0.11. <details> <summary>Release notes</summary> _Sourced from [Microsoft.Extensions.DependencyInjection.Abstractions's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Updated [Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore](https://github.com/dotnet/dotnet) from 10.0.10 to 10.0.11. <details> <summary>Release notes</summary> _Sourced from [Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Updated [Microsoft.Extensions.Diagnostics.Testing](https://github.com/dotnet/extensions) from 10.8.0 to 10.9.0. <details> <summary>Release notes</summary> _Sourced from [Microsoft.Extensions.Diagnostics.Testing's releases](https://github.com/dotnet/extensions/releases)._ ## 10.9.0 Version 10.9.0 is headlined by changes in these areas: * **AI:** New experimental routing APIs center on the abstract `RoutingChatClient` base class, with `SemanticRoutingChatClient` as a concrete semantic-routing implementation. Separately, the abstract `FailoverChatClient` specialization and its concrete `OrderedFailoverChatClient` implementation add failover routing. * **AI Evaluation:** The generated report gains redesigned Overview, Cases, History, and Comparison views. * **ASP.NET Core and HTTP diagnostics:** The release adds HTTP request latency log enrichment and fixes configuration binding, response-body logging, request-path redaction, and resilience package version handling. * **Source-generated logging and service discovery:** Fixes cover classification type qualification, thread-local state cleanup, and DNS query suffix handling. ## Experimental API Changes ### New Experimental APIs * New experimental API: HTTP request latency log enrichment (`EXTEXP0013`) #7602 * New experimental API: Chat client routing and failover (`MEAI001`) #7662 ## What's Changed ### AI (`Microsoft.Extensions.AI`, `Microsoft.Extensions.AI.Abstractions`, and `Microsoft.Extensions.AI.OpenAI`) * Add extensible chat client routing #7662 by @joshuajyue (co-authored by @Copilot) * Pass the request's options to the selected client #7685 by @joshuajyue (co-authored by @jozkee @Copilot) * AI.Abstractions: fix ExcludeFromSchema dropped under concurrent AIFunction creation #7677 by @jozkee (co-authored by @Copilot) * Cap OpenAI dependency version ([b10f9c0](dotnet/extensions@b10f9c0)) by @jeffhandley (co-authored by @Copilot) **Note: Microsoft.Extensions.AI.OpenAI constrains its dependency for OpenAI to 2.12.x, preventing OpenAI updates to 2.13.0+ due to an incompatibility. We expect to release Microsoft.Extensions.AI.OpenAI version 10.9.1 during the week of August 17 to address this issue.** ### HTTP Resilience and Diagnostics (`Microsoft.Extensions.Http.Resilience` and `Microsoft.Extensions.Http.Diagnostics`) * Fix Grpc.Net.ClientFactory version range check - Fixes #7565 #7566 by @Ghost93 * Fix response body logging under debugger #7678 by @Rimobul * Redact outgoing path when route is unknown #7687 by @Rimobul * Fix HTTP client logging config binding #7691 by @Rimobul ### ASP.NET Core Extensions (`Microsoft.AspNetCore.Diagnostics.Middleware`) * Rename HttpLatencyTelemetry extensions class and drop redundant TFM guard #7645 by @EasyL0ver (co-authored by @Copilot) * Add HTTP request latency log enricher (experimental) #7602 by @EasyL0ver (co-authored by @Copilot) ### Logging Source Generator (`Microsoft.Gen.Logging`) * [Microsoft.Gen.Logging] Clear thread-local state when logging throws #7682 by @Rimobul * [Microsoft.Gen.Logging] Fully qualify classification types #7689 by @Rimobul ### AI Evaluation (`Microsoft.Extensions.AI.Evaluation.Reporting`) * [Microsoft.Extensions.AI.Evaluation.Reporting] Evaluation report redesign #7609 by @grafanaKibana ### Project Templates (`Microsoft.McpServer.ProjectTemplates`) * Remove MCP server project template #7680 by @jeffhandley (co-authored by @Copilot) ... (truncated) ## 10.8.4 This servicing update refreshes the .NET AI project templates ahead of the July 30, 2026 retirement of GitHub Models — removing the GitHub Models provider option and updating template dependencies. As a result, both the AI Chat Web (`aichatweb`) and AI Agent Web API (`aiagent-webapi`) templates now **require** the AI service provider to be chosen explicitly via `--provider`; there is no longer a default. One of the following must be selected: - `--provider azureopenai` — Azure OpenAI - `--provider ollama` — Ollama (for local development) - `--provider openai` — OpenAI Platform ## Packages in this release | Package | Version | |---|---| | Microsoft.Extensions.AI.Templates | 10.8.4-preview.3.26379.3 | | Microsoft.Agents.AI.ProjectTemplates | 1.13.0-preview.1.26379.3 | ## What's Changed ### Project templates - **Removed the GitHub Models provider** from the AI Chat Web and AI Agent Web API templates, ahead of [GitHub Models being fully retired on July 30, 2026](https://github.blog/changelog/2026-07-01-github-models-is-being-fully-retired-on-july-30-2026/). The `--provider` option is now required with no default ([#7667](dotnet/extensions#7667)). - Updated AI template dependencies — bumped `Aspire.Hosting.AppHost` to `13.4.6` and `CommunityToolkit.VectorData.SqliteVec` to `1.0.0-preview.4` (aligned `System.Linq.AsyncEnumerable` to `10.0.9`), replacing earlier workaround package pins ([#7639](dotnet/extensions#7639)). ## Full Changelog - dotnet/extensions@v10.8.3...v10.8.4 ## 10.8.3 ## Packages in this release | Package | Version | |---|---| | Microsoft.Extensions.AI | 10.8.3 | | Microsoft.Extensions.AI.Abstractions | 10.8.3 | | Microsoft.Extensions.AI.OpenAI | 10.8.3 | ## Experimental API Changes ### Experimental API behavior updates - Updated serialization behavior for experimental `ToolApprovalRequestContent.RequiresConfirmation` so it no longer leaks into consumer source-generated `AIContent` JSON metadata unless approval APIs are intentionally used ([#7659](dotnet/extensions#7659)). ## What's Changed ### AI abstractions and serialization - Fixed MEAI001 leakage from `RequiresConfirmation` in source-generated `AIContent` contexts by using an internal JSON-included backing member while keeping the public experimental member ignored for source-generation metadata ([#7659](dotnet/extensions#7659)). ## Test Improvements - Added stabilization regression coverage to verify consumer source-generated `List<AIContent>` contexts compile and round-trip without requiring MEAI001 suppression ([#7659](dotnet/extensions#7659)). ## Full Changelog - dotnet/extensions@v10.8.2...v10.8.3 ## 10.8.2 This servicing release updates Microsoft.Extensions.VectorData.ConformanceTests to 10.8.2 and includes targeted test framework migration fixes. ## Packages in this release | Package | Version | Note | |---------|---------|---------| | Microsoft.Extensions.VectorData.Abstractions | 10.8.2 | Published August 7, 2026 | | Microsoft.Extensions.VectorData.ConformanceTests | 10.8.2 | | **Update: August 7, 2026** The Microsoft.Extensions.VectorData.Abstractions package was initially excluded from this release by mistake. Because Microsoft.Extensions.VectorData.ConformanceTests has a dependency on Microsoft.Extensions.VectorData.Abstractions, that led to failures when updating to Microsoft.Extensions.VectorData.ConformanceTests 10.8.2. Microsoft.Extensions.VectorData.Abstractions was published August 7, 2026 to resolve that issue. ## What's Changed ### AI * Move Microsoft.Extensions.VectorData.ConformanceTests to xUnit 3 #7636 by @adamsitnik (co-authored by @Copilot) ## Acknowledgements * @roji reviewed pull requests **Full Changelog**: dotnet/extensions@v10.8.1...v10.8.2 ## 10.8.1 This servicing release updates the Microsoft.Extensions.AI, Microsoft.Extensions.AI.Abstractions, and Microsoft.Extensions.AI.OpenAI packages to 10.8.1 with two targeted fixes: correct tool-call/tool-result ordering when resuming approval-gated functions with service-managed chat history, and preservation of the OpenAI Responses reasoning item id for stateless (store=false) encrypted reasoning. ## Packages in this release | Package | Version | |---------|---------| | Microsoft.Extensions.AI | 10.8.1 | | Microsoft.Extensions.AI.Abstractions | 10.8.1 | | Microsoft.Extensions.AI.OpenAI | 10.8.1 | ## What's Changed ### AI * Fix FICC tool_calls/tool ordering with approvals and service-managed chat history #7617 by @westey-m * Roundtrip OpenAI Responses reasoning item id for stateless (store=false) encrypted reasoning #7629 by @rogerbarreto (co-authored by @tarekgh) ## Acknowledgements * @jozkee reviewed pull requests **Full Changelog**: dotnet/extensions@v10.8.0...v10.8.1 Commits viewable in [compare view](dotnet/extensions@v10.8.0...v10.9.0). </details> Updated [Microsoft.Extensions.Http](https://github.com/dotnet/dotnet) from 10.0.10 to 10.0.11. <details> <summary>Release notes</summary> _Sourced from [Microsoft.Extensions.Http's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This was referenced Aug 13, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tracks #7658
Problem
ToolApprovalRequestContent.RequiresConfirmationis[Experimental(MEAI001)], whileToolApprovalRequestContentis a stable, statically registered[JsonDerivedType]of the[JsonPolymorphic]AIContentandInputRequestContenthierarchies. This regression was introduced in 10.8.0 by Add ToolApprovalRequestContent.RequiresConfirmation (#7549).As a result, System.Text.Json source generation emits the experimental member into the JSON metadata for any consumer context that reaches
AIContent, even when the consumer never uses approval APIs:The build emits
MEAI001from source-generated code. Consumers are then forced into a project-wide suppression as the only practical remedy, but the suppression does not remove the member from their generated contract: their externally exposed JSON payloads still include the experimentalrequiresConfirmationfield without an approval-feature opt-in.Fix
ToolApprovalRequestContentis stable; onlyRequiresConfirmationis experimental. Keep the type in the static polymorphic contract, but gate its serialization at the member level using the established pattern used byUsageDetailstoken counts andHostedFileContent:The internal member remains available to the package-owned default serialization path, so persisted conversations continue to round-trip
requiresConfirmation. Consumer source-generated contracts omit the experimental field, and direct use of the public property continues to requireMEAI001opt-in.The two
Microsoft.Extensions.AI.Evaluation.Reportingprojects had gained<NoWarn>$(NoWarn);MEAI001</NoWarn>alongside #7549 solely because of this leak. The fix removes both suppressions; their clean builds demonstrate that they were leak-driven.AbstractionsandAIretain their suppressions because they legitimately use experimental APIs directly.Regression coverage
Adds a no-suppression consumer-boundary guard in
Microsoft.Extensions.AI.Stabilization.Tests:AIContentSerializationRegressionContext.cssource-generatesList<AIContent>. Any experimental member leaking into the contract producesMEAI001at compile time.AIContentSerializationRegressionTests.csconfirms stableList<AIContent>round-trips through that generated context.ToolApprovalRequestContenttests verifyRequiresConfirmationstill round-trips as bothtrueandfalsethroughAIJsonUtilities.DefaultOptionsandAIContentpolymorphism.Validation
Microsoft.Extensions.AI.Stabilization.Tests: 90/90 pass across net472, net8.0, net9.0, and net10.0 without an MEAI001 suppression.Microsoft.Extensions.AI.Abstractions.Tests: 1634 pass; the intended persistence round-trip remains intact.MEAI001in the generatedAIContentSerializationRegressionContext.ToolApprovalRequestContent.g.csacross all four target frameworks.Microsoft Reviewers: Open in CodeFlow