Skip to content

Honor UnmappedMemberHandling in AIFunctionFactory parameter binding#7474

Open
eiriktsarpalis wants to merge 4 commits intodotnet:mainfrom
eiriktsarpalis:aifunction-honor-unmapped-member-handling
Open

Honor UnmappedMemberHandling in AIFunctionFactory parameter binding#7474
eiriktsarpalis wants to merge 4 commits intodotnet:mainfrom
eiriktsarpalis:aifunction-honor-unmapped-member-handling

Conversation

@eiriktsarpalis
Copy link
Copy Markdown
Member

@eiriktsarpalis eiriktsarpalis commented Apr 17, 2026

Follow-up to the discussion in modelcontextprotocol/csharp-sdk#1508.

Today, AIFunctionFactory silently ignores keys in the AIFunctionArguments dictionary 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. markComplete vs phase in the linked issue).

This change wires JsonSerializerOptions.UnmappedMemberHandling into top-level parameter binding:

  • When the serializer options have UnmappedMemberHandling = Disallow, invoking the AIFunction now throws ArgumentException if AIFunctionArguments contains a key that doesn't match any method parameter (infrastructure parameters CancellationToken / AIFunctionArguments / IServiceProvider are excluded from the permitted set, as they are never addressed by name).
  • The default behavior (Skip) is unchanged, so this is opt-in and non-breaking.
  • Documented on AIFunctionFactoryOptions.SerializerOptions.
  • Added unit tests for both the strict and default code paths.

Closes the MEAI side of modelcontextprotocol/csharp-sdk#1508.

Microsoft Reviewers: Open in CodeFlow

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>
@eiriktsarpalis eiriktsarpalis requested a review from a team as a code owner April 17, 2026 13:04
Copilot AI review requested due to automatic review settings April 17, 2026 13:04
@github-actions github-actions bot added the area-ai Microsoft.Extensions.AI libraries label Apr 17, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.InvokeAsync when UnmappedMemberHandling=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.

Comment thread src/Libraries/Microsoft.Extensions.AI.Abstractions/Functions/AIFunctionFactory.cs Outdated
eiriktsarpalis and others added 3 commits April 17, 2026 13:10
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-ai Microsoft.Extensions.AI libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants