Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 12, 2025

Implementation: Add Reason property to FunctionApprovalResponseContent

Changes Completed

  • Add nullable Reason property to FunctionApprovalResponseContent class

    • Added "optional" to property documentation as suggested
    • Removed verbose <remarks> section for cleaner documentation
  • Update FunctionInvokingChatClient.GenerateRejectedFunctionResults method

    • Changed rejection message format to always include "Tool call invocation rejected."
    • Appends custom reason when provided: "Tool call invocation rejected. {Reason}"
    • Uses IsNullOrWhiteSpace check as suggested
  • Update all tests for new message format

    • Updated default rejection message expectations
    • Updated custom reason expectations to include prefix
    • All FunctionInvokingChatClientApprovalsTests pass across .NET 8, 9, and 10
  • Add serialization tests for Reason property

    • Updated FunctionApprovalResponseContentTests.Serialization_Roundtrips to test with both null and custom reason
    • Ensures Reason property correctly serializes and deserializes through JSON
  • Add edge case tests for Reason property

    • Added RejectedApprovalResponsesWithEmptyOrWhitespaceReasonUsesDefaultMessageAsync test
    • Tests null, empty string, and whitespace-only values
    • Validates that IsNullOrWhiteSpace logic treats all as default message
  • Build and test validation

    • All builds passed successfully (Debug configuration)
    • All 22 FunctionInvokingChatClientApprovalsTests pass
    • All 6 FunctionApprovalResponseContentTests pass
  • Code review feedback addressed

    • Simplified property documentation
    • Improved rejection message format to avoid ambiguity
    • Added comprehensive test coverage per reviewer suggestions

Summary

All PR review feedback has been addressed. The rejection message now clearly indicates it's a rejection while allowing custom context to be appended. The implementation includes proper serialization support and comprehensive edge case testing to document behavior with empty/whitespace/null reasons.

Original prompt

This section details on the original issue you should resolve

<issue_title>Provide ability to specify reject message for FunctionInvokingChatClient</issue_title>
<issue_description>The reject message for FunctionApprovalResponseContent with Approved = false is currently a hard-coded string:

"Error: Tool call invocation was rejected by user."

However, this situation is not necessarily an error. It should be possible to provide a custom rejection message, allowing callers to specify the actual reason for rejection.

Relevant code:

rejections.ConvertAll(static m => (AIContent)new FunctionResultContent(m.Response.FunctionCall.CallId, "Error: Tool call invocation was rejected by user.")) :

</issue_description>

<agent_instructions>Please add a nullable string Reason get/set property to FunctionApprovalResponseContent. If such a reason is set, FunctionInvokingChatClient should factor that into the FunctionResultContent message it creates for rejected tool calls. The property can currently be ignored for Approval=true, though it's conceivable the message might be used for something in the future, and if nothing else, it'll show up in tracing/logging/etc. when the content is serialized.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Microsoft Reviewers: Open in CodeFlow

Copilot AI changed the title [WIP] Add ability to specify reject message for FunctionInvokingChatClient Add Reason property to FunctionApprovalResponseContent for custom rejection messages Dec 12, 2025
Copilot AI requested a review from stephentoub December 12, 2025 16:15
Copy link
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

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

@stephentoub
Copy link
Member

@NoofSaeidh, does this address your scenarios / concerns from #7139?

@stephentoub stephentoub marked this pull request as ready for review December 12, 2025 16:37
@stephentoub stephentoub requested a review from a team as a code owner December 12, 2025 16:37
Copilot AI review requested due to automatic review settings December 12, 2025 16:37
@stephentoub
Copy link
Member

cc: @rogerbarreto, @westey-m, @jozkee

@ericstj ericstj added the area-ai Microsoft.Extensions.AI libraries label Dec 12, 2025
Copy link
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 adds a nullable Reason property to FunctionApprovalResponseContent to enable custom rejection messages for function call approvals. Previously, rejected function calls used a hard-coded error message. Now, users can provide specific reasons for rejections that will be included in the function result content sent to the downstream client.

Key Changes:

  • Added Reason property (nullable string, get/set) to FunctionApprovalResponseContent with documentation indicating it's optional and can be used for both approval and rejection
  • Updated rejection message format in FunctionInvokingChatClient.GenerateRejectedFunctionResults from "Error: Tool call invocation was rejected by user." to "Tool call invocation rejected." with optional custom reason appended when provided
  • Updated all existing test expectations to match the new default rejection message format and added comprehensive tests for custom rejection reasons

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/FunctionApprovalResponseContent.cs Adds nullable Reason property to allow custom messages for approval/rejection responses
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/FunctionInvokingChatClient.cs Updates GenerateRejectedFunctionResults to use new rejection message format and append custom reason when provided using IsNullOrWhiteSpace check
test/Libraries/Microsoft.Extensions.AI.Tests/ChatCompletion/FunctionInvokingChatClientApprovalsTests.cs Updates existing test expectations for new default message format and adds two comprehensive tests (RejectedApprovalResponsesWithCustomReasonAsync and MixedApprovalResponsesWithCustomAndDefaultReasonsAsync) covering custom rejection reasons

@stephentoub
Copy link
Member

@copilot, please address the feedback

@NoofSaeidh
Copy link

@NoofSaeidh, does this address your scenarios / concerns from #7139?

Yes, thank you!

@stephentoub stephentoub enabled auto-merge (squash) December 15, 2025 04:35
@NoofSaeidh
Copy link

NoofSaeidh commented Dec 15, 2025

@stephentoub actually looks like it is worth to add Reason into the CreateResponse method in FunctionApprovalRequestContent

public FunctionApprovalResponseContent CreateResponse(bool approved) => new(Id, approved, FunctionCall);

@stephentoub
Copy link
Member

@stephentoub actually looks like it is worth to add Reason into the CreateResponse method in FunctionApprovalRequestContent

public FunctionApprovalResponseContent CreateResponse(bool approved) => new(Id, approved, FunctionCall);

Why not just set the property on the resulting object?

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.

Provide ability to specify reject message for FunctionInvokingChatClient

5 participants