Skip to content

AI: Restore neutral tool approval rejection message - #7913

Open
jozkee wants to merge 1 commit into
mainfrom
agents/ficc-approval-rejection-handling
Open

jozkee wants to merge 1 commit into
mainfrom
agents/ficc-approval-rejection-handling

Conversation

@jozkee

@jozkee jozkee commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Fixes #7914.

Summary

Reverts the rejection-message change from #7784, restoring Tool call invocation rejected. and the corresponding test expectations. Also clarifies that callers can use ToolApprovalResponseContent.Reason to express whether a rejection is final or a new call may be requested for approval.

Why

A rejected approval does not always represent a final approver decision. Microsoft Agent Framework automatically rejects unanswered approval requests to recover from interrupted sessions. The unconditional "rejected by the approver and must not be retried" prefix incorrectly attributes those rejections and prevents the intended recovery through a new tool call with fresh approval. Appending a custom reason cannot reliably override that contradictory prefix.

Keep the default message neutral and leave finality/recovery guidance to the caller through the existing optional Reason. Rejected calls remain unexecuted; this does not authorize retries without fresh approval. Reason remains nullable and has no default, since it is used for both approvals and rejections.

This restores pre-#7784 behavior: callers that need to discourage repeated approval requests should explicitly state that policy in Reason.

Related: microsoft/agent-framework#9656 and microsoft/agent-framework#8849.

Validation

  • Built the test project and its dependencies across net10.0, net9.0, net8.0, and net472.
  • All 46 FunctionInvokingChatClientApprovalsTests passed on each framework (184 total), covering streaming and non-streaming approval handling, custom/default reasons, and mixed approvals.
  • git diff --check passed.
  • Build emitted Verify's missing-solution auto-discovery warning when building the project directly; no build or test failures.

Command:

dotnet test .\test\Libraries\Microsoft.Extensions.AI.Tests\Microsoft.Extensions.AI.Tests.csproj -- --filter-class '*FunctionInvokingChatClientApprovalsTests'
Microsoft Reviewers: Open in CodeFlow

Revert the finality wording from #7784 so automatic rejection of unanswered approvals does not prohibit a new call with fresh approval. Keep policy guidance in the optional Reason and document that usage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jozkee
jozkee requested a review from a team as a code owner November 3, 2026 18:23
Copilot AI balanced review requested due to automatic review settings November 3, 2026 18:23
@github-actions github-actions Bot added the area-ai Microsoft.Extensions.AI libraries label Nov 3, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues are reported for the neutral rejection-message and caller-guidance changes.

No open issues 🎉

What changed in this PR

Restores neutral tool-approval rejection wording in the AI function-invocation middleware, allowing callers to communicate finality or recovery guidance through Reason without a contradictory default message. Rejected calls remain unexecuted.

Changes:

  • Restores Tool call invocation rejected., reverting the wording introduced in #7784.
  • Documents how Reason can clarify whether rejection is final or fresh approval may be requested.
  • Updates existing approval tests to expect the neutral message.
File Description
test/​Libraries/​Microsoft.Extensions.AI.Tests/​ChatCompletion/​FunctionInvokingChatClientApprovalsTests.cs Updates rejection-message expectations across approval scenarios.
src/​Libraries/​Microsoft.Extensions.AI/​ChatCompletion/​FunctionInvokingChatClient.cs Restores the neutral default rejection message.
src/​Libraries/​Microsoft.Extensions.AI.Abstractions/​Contents/​ToolApprovalResponseContent.cs Adds documentation explaining caller-provided rejection guidance through Reason.

Review effort: Balanced

@jozkee

jozkee commented Nov 3, 2026

Copy link
Copy Markdown
Member Author

@manjunathshiva, heads up: this reverts #7784 because the finality wording breaks MAF’s recovery from unanswered approvals. FICC shouldn’t prescribe retry policy for every rejection; callers can express finality through Reason.

@dotnet-comment-bot

Copy link
Copy Markdown
Collaborator

‼️ Found issues ‼️

Project Coverage Type Expected Actual
Microsoft.Extensions.AI Line 89 87.21 🔻
Microsoft.Extensions.AI Branch 89 79.21 🔻
Microsoft.Extensions.AI.OpenAI Line 75 68.82 🔻
Microsoft.Extensions.AI.OpenAI Branch 75 60.26 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Line 75 4.46 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Branch 75 0.75 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Line 99 96.06 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Branch 99 92.28 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Line 99 97.73 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Branch 99 92.86 🔻
Microsoft.Extensions.Diagnostics.Testing Line 99 98.22 🔻
Microsoft.Extensions.Diagnostics.Testing Branch 99 93.71 🔻
Microsoft.Extensions.ServiceDiscovery Line 75 61.99 🔻
Microsoft.Extensions.ServiceDiscovery Branch 75 64.51 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Line 75 41.14 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Branch 75 45.1 🔻
Microsoft.Extensions.ServiceDiscovery.Dns Line 75 67.15 🔻
Microsoft.Extensions.ServiceDiscovery.Dns Branch 75 73.96 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Line 75 73.85 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Branch 75 60 🔻
Microsoft.Extensions.Telemetry Line 93 90.46 🔻
Microsoft.Extensions.Telemetry Branch 93 86.78 🔻
Microsoft.Extensions.VectorData.Abstractions Line 75 32.15 🔻
Microsoft.Extensions.VectorData.Abstractions Branch 75 26.31 🔻

🎉 Good job! The coverage increased 🎉
Update MinCodeCoverage in the project files.

Project Expected Actual
Microsoft.Extensions.AI.Evaluation.NLP 0 74
Microsoft.Extensions.DataIngestion 75 77
Microsoft.Extensions.DataIngestion.Markdig 75 88
Microsoft.Extensions.Http.Resilience 97 99
Microsoft.Gen.MetadataExtractor 57 72
Microsoft.Gen.MetricsReports 67 69

Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1662283&view=codecoverage-tab

This branch has not been deployed

No deployments
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.

FunctionInvokingChatClient: the "must not be retried" rejection message is wrong when no one actually said no

4 participants