Honor UnmappedMemberHandling in AIFunctionFactory parameter binding#7474
Open
eiriktsarpalis wants to merge 4 commits intodotnet:mainfrom
Open
Honor UnmappedMemberHandling in AIFunctionFactory parameter binding#7474eiriktsarpalis wants to merge 4 commits intodotnet:mainfrom
eiriktsarpalis wants to merge 4 commits intodotnet:mainfrom
Conversation
When JsonSerializerOptions.UnmappedMemberHandling is set to Disallow, AIFunction invocations will now throw ArgumentException if the provided AIFunctionArguments contains keys that do not correspond to any declared parameter of the underlying method. This mirrors STJ's handling of unmapped properties for object deserialization and enables opt-in strict validation of tool call arguments. Addresses discussion in modelcontextprotocol/csharp-sdk#1508. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates AIFunctionFactory’s top-level argument binding to optionally enforce strict validation of AIFunctionArguments keys when JsonSerializerOptions.UnmappedMemberHandling is set to Disallow, aligning dictionary binding behavior with System.Text.Json’s unmapped-member handling semantics.
Changes:
- Enforce strict “no extra keys” validation during
AIFunction.InvokeAsyncwhenUnmappedMemberHandling=Disallow. - Document the new strict-validation behavior on
AIFunctionFactoryOptions.SerializerOptions. - Add unit tests covering both strict (
Disallow) and default (Skip) behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| test/Libraries/Microsoft.Extensions.AI.Tests/Functions/AIFunctionFactoryTest.cs | Adds tests validating strict vs default handling of extra argument keys. |
| src/Libraries/Microsoft.Extensions.AI.Abstractions/Functions/AIFunctionFactoryOptions.cs | Documents how UnmappedMemberHandling=Disallow affects invocation-time argument validation. |
| src/Libraries/Microsoft.Extensions.AI.Abstractions/Functions/AIFunctionFactory.cs | Implements invocation-time unmapped argument key validation and precomputes expected argument names. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Always build the expected-argument-name set (even if empty) so strict mode also flags extra keys on parameterless methods / methods with only infrastructure parameters. - Skip strict unmapped-key validation when any parameter uses a custom ParameterBindingOptions.BindParameter callback, since those may legitimately consume arbitrary argument keys. - Expanded the XML docs on AIFunctionFactoryOptions.SerializerOptions to clarify which parameter names are considered valid and that custom parameter binding bypasses the strict check. - Added tests for both new behaviors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Follow-up to the discussion in modelcontextprotocol/csharp-sdk#1508.
Today,
AIFunctionFactorysilently ignores keys in theAIFunctionArgumentsdictionary that do not correspond to any declared parameter of the underlying method. This matches STJ's default lenient handling of unmapped properties, but it prevents tool servers from opting in to strict validation when an LLM hallucinates an extra argument name (e.g.markCompletevsphasein the linked issue).This change wires
JsonSerializerOptions.UnmappedMemberHandlinginto top-level parameter binding:UnmappedMemberHandling = Disallow, invoking theAIFunctionnow throwsArgumentExceptionifAIFunctionArgumentscontains a key that doesn't match any method parameter (infrastructure parametersCancellationToken/AIFunctionArguments/IServiceProviderare excluded from the permitted set, as they are never addressed by name).Skip) is unchanged, so this is opt-in and non-breaking.AIFunctionFactoryOptions.SerializerOptions.Closes the MEAI side of modelcontextprotocol/csharp-sdk#1508.
Microsoft Reviewers: Open in CodeFlow