You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When toolautocall converts all FunctionCallContent items to ToolApprovalRequestContent (because at least one tool in a response requires approval), the toolapproval middleware now automatically approves requests for tools that are not marked as approval-required via tool.ApprovalRequiredTool. Callers only see approval requests for tools that genuinely need human sign-off.
The key changes in toolapproval.go:
Add isNotApprovalRequired(req, opts) — checks the registered tool list in opts; if the named tool is found and does not implement tool.ApprovalRequiredTool (or implements it and returns false), the request is auto-approved. Returns false conservatively when the tool is not found.
Update the classification loop in run() to use matchesRule(st.Rules, req) || isNotApprovalRequired(req, opts), so non-approval-required tools are handled transparently alongside standing-rule matches.
Update drainAutoApprovable to accept opts and apply the same check, so queued requests from a prior turn are drained when the corresponding tool is now registered as non-approval-required.
The Go implementation diverges from .NET in structure (no separate decorator class; the logic lives directly in the existing toolapproval middleware), but the user-visible semantics are the same: non-approval-required tools in a mixed batch are approved automatically without surfacing to the caller.
Breaking Changes
No. The isNotApprovalRequired helper is conservative: it only auto-approves when the tool is positively identified in opts as not requiring approval. Existing callers that do not register tools via agent.WithTool, or that register all tools via tool.ApprovalRequiredFunc, see identical behavior.
Tests and Examples
Existing tests all pass unchanged.
Two new tests added in agent/harness/toolapproval/toolapproval_test.go:
TestToolApproval_NonApprovalRequiredToolAutoApproved — mixed batch (approval-required deploy + non-required list): only deploy is surfaced; list is auto-approved and its response is forwarded to the inner agent on the next round.
TestToolApproval_NonApprovalRequiredQueuedRequestDrained — a list request queued in a prior turn (when no tools were registered) is drained automatically once list is registered as non-approval-required in the current turn.
Run with:
go test ./agent/harness/toolapproval/...
Notes
This change is complementary to the open PR #254 (auto-approval rules/heuristics). PR #254 adds user-supplied callback rules evaluated at classification time; this PR adds system-level auto-approval based on the tool's own ApprovalRequired() declaration. Both paths feed into the same autoApproved bucket in the classification loop.
The .NET NonApprovalRequiredFunctionBypassingChatClient is opt-in (EnableNonApprovalRequiredFunctionBypassing config flag). In Go, the behavior is always-on because the misalignment (non-approval-required tools appearing as approval requests) is an implementation artifact of the all-or-nothing FCC conversion, not an intentional design choice. The conservative fallback (unknown tool → require approval) preserves backward compatibility.
This was originally intended as a pull request, but GitHub Actions is not permitted to create or approve pull requests in this repository.
The changes have been pushed to branch dotnet-port/toolapproval-non-required-bypass-91e11298bcf6b8f0.
To fix the permissions issue, go to Settings → Actions → General and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ
Show patch preview (320 of 320 lines)
From 1be7c53f5f779267b8fb66dd5a319d278f2515b7 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Mon, 8 Jun 2026 10:37:06 +0000
Subject: [PATCH] toolapproval: auto-approve non-approval-required tools in
mixed batches
When toolautocall converts all FunctionCallContents to ToolApprovalRequestContent
(because any tool requires approval), the toolapproval middleware now automatically
approves requests for tools that are not marked as approval-required via
tool.ApprovalRequiredTool.
This mirrors the behavior of .NET's NonApprovalRequiredFunctionBypassingChatClient
(microsoft/agent-framework#4950): callers only see approval requests for tools that
genuinely require human sign-off. Non-approval-required requests are silently
collected and forwarded to the inner agent on the next round.
The new isNotApprovalRequired helper is conservative: it returns false (requiring
approval) when the tool cannot be found in opts, so the change is backward-compatible
with callers that do not register tools via agent.WithTool.
drainAutoApprovable also applies the same check so queued non-approval-required
requests (enqueued in a prior turn when the tool was not yet registered) are drained
automatically without user intervention.
Add two tests covering:
- Mixed approval batch: only approval-required deploy is surfaced; non-approval-required list is auto-approved.- Queued drain: a previously queued list request is drained on the next turn once list is registered as non-approval-required.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
agent/harness/toolapproval/toolapproval.go | 38 +++-
.../harness/toolapproval/toolapproval_test.go | 186 ++++++++++++++++++
2 files changed, 217 insertions(+), 7 deletions(-)
diff --git a/agent/harness/toolapproval/toolapproval.go b/agent/harness/toolapproval/toolapproval.go
index 3683b7f8..4a2632b6 100644
--- a/agent/harness/toolapproval/toolapproval.go+++ b/agent/h
... (truncated)
Summary
When
toolautocallconverts allFunctionCallContentitems toToolApprovalRequestContent(because at least one tool in a response requires approval), thetoolapprovalmiddleware now automatically approves requests for tools that are not marked as approval-required viatool.ApprovalRequiredTool. Callers only see approval requests for tools that genuinely need human sign-off.The key changes in
toolapproval.go:isNotApprovalRequired(req, opts)— checks the registered tool list inopts; if the named tool is found and does not implementtool.ApprovalRequiredTool(or implements it and returnsfalse), the request is auto-approved. Returnsfalseconservatively when the tool is not found.run()to usematchesRule(st.Rules, req) || isNotApprovalRequired(req, opts), so non-approval-required tools are handled transparently alongside standing-rule matches.drainAutoApprovableto acceptoptsand apply the same check, so queued requests from a prior turn are drained when the corresponding tool is now registered as non-approval-required.Ported .NET PRs
NonApprovalRequiredFunctionBypassingChatClient)The Go implementation diverges from .NET in structure (no separate decorator class; the logic lives directly in the existing
toolapprovalmiddleware), but the user-visible semantics are the same: non-approval-required tools in a mixed batch are approved automatically without surfacing to the caller.Breaking Changes
No. The
isNotApprovalRequiredhelper is conservative: it only auto-approves when the tool is positively identified inoptsas not requiring approval. Existing callers that do not register tools viaagent.WithTool, or that register all tools viatool.ApprovalRequiredFunc, see identical behavior.Tests and Examples
Existing tests all pass unchanged.
Two new tests added in
agent/harness/toolapproval/toolapproval_test.go:TestToolApproval_NonApprovalRequiredToolAutoApproved— mixed batch (approval-requireddeploy+ non-requiredlist): onlydeployis surfaced;listis auto-approved and its response is forwarded to the inner agent on the next round.TestToolApproval_NonApprovalRequiredQueuedRequestDrained— alistrequest queued in a prior turn (when no tools were registered) is drained automatically oncelistis registered as non-approval-required in the current turn.Run with:
Notes
This change is complementary to the open PR #254 (auto-approval rules/heuristics). PR #254 adds user-supplied callback rules evaluated at classification time; this PR adds system-level auto-approval based on the tool's own
ApprovalRequired()declaration. Both paths feed into the sameautoApprovedbucket in the classification loop.The .NET
NonApprovalRequiredFunctionBypassingChatClientis opt-in (EnableNonApprovalRequiredFunctionBypassingconfig flag). In Go, the behavior is always-on because the misalignment (non-approval-required tools appearing as approval requests) is an implementation artifact of the all-or-nothing FCC conversion, not an intentional design choice. The conservative fallback (unknown tool → require approval) preserves backward compatibility.Note
This was originally intended as a pull request, but GitHub Actions is not permitted to create or approve pull requests in this repository.
The changes have been pushed to branch
dotnet-port/toolapproval-non-required-bypass-91e11298bcf6b8f0.Click here to create the pull request
To fix the permissions issue, go to Settings → Actions → General and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ
Show patch preview (320 of 320 lines)