Support non-object arguments for external tools - #2496
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The reviewed implementation and tests have no unresolved approval-blocking issues.
Review tier: Balanced
Findings: None
What changed in this PR
Adds .NET support for external tools receiving non-object JSON arguments while preserving object-property binding.
Changes:
- Binds non-object JSON to the sole or sole-required schema parameter.
- Rejects ambiguous schemas with a clear error.
- Adds coverage for string, numeric, optional-parameter, successful, and rejected invocations.
| File | Description |
|---|---|
dotnet/src/Session.cs |
Implements non-object argument binding and schema validation. |
dotnet/test/Unit/ClientSessionLifetimeTests.cs |
Adds fake-server coverage and tool-response handling. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Cross-SDK Consistency ReviewReviewed the change to Assessment: no cross-SDK parity gap. This bug is unique to the .NET SDK's API design: The other SDKs don't have this failure mode because they don't reflectively bind incoming arguments to individual function parameters:
So a non-object No action needed in other SDKs.
|
SteveSandersonMS
left a comment
There was a problem hiding this comment.
Approving — this is a well-scoped, verified fix for a real crash when overriding apply_patch (and any other built-in tool that sends a bare string/number argument) in the .NET SDK. I reverted the source change locally and confirmed the new tests fail with the exact EnumerateObject-on-non-object exception this PR fixes, then confirmed they pass with the fix restored and the rest of the 57-test suite is unaffected. Confirmed this is .NET-specific (other SDKs pass raw JSON through without reflective binding), so no other-language changes are needed.
External tool overrides such as
apply_patchcan receive freeform JSON values, but the .NET SDK previously assumed every invocation root was an object and failed before entering the host handler.This change preserves named-property expansion for object roots and binds any non-object JSON value to the function's sole schema parameter. When additional parameters are optional, it selects the sole required parameter; ambiguous schemas return a clear tool error instead of guessing. Fake-server coverage exercises string and numeric values, optional parameters, successful responses, and ambiguous rejection.
Tests
dotnet test dotnet\test\GitHub.Copilot.SDK.Test.csproj --filter "FullyQualifiedName~GitHub.Copilot.Test.Unit.ClientSessionLifetimeTests" --no-restoreGenerated by Copilot