Python: Integrate tool approval into the harness - #6522
Merged
westey (westey-m) merged 5 commits intoJun 16, 2026
Conversation
westey (westey-m)
had a problem deploying
to
integration
June 15, 2026 13:48 — with
GitHub Actions
Error
westey (westey-m)
had a problem deploying
to
integration
June 15, 2026 13:48 — with
GitHub Actions
Error
Contributor
Contributor
There was a problem hiding this comment.
Pull request overview
This PR brings the Python harness agent (create_harness_agent) closer to .NET parity by enabling tool-approval handling by default, and updates the harness console sample to let users create standing “don’t ask again” approvals. It also hardens the console tool-call formatter against non-dict JSON argument payloads and adds unit coverage for the new harness wiring behavior.
Changes:
- Wire
ToolApprovalMiddlewareby default increate_harness_agent, withdisable_tool_approvalopt-out andauto_approval_rulesforwarding. - Extend the harness console approval prompt to support “always approve” (tool-wide and tool+arguments) responses.
- Add tests validating middleware installation/ordering and update harness README to list the feature.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| python/samples/02-agents/harness/README.md | Documents tool approval as a default harness feature. |
| python/samples/02-agents/harness/console/observers/tool_approval.py | Adds “always approve” options using standing-approval helper responses. |
| python/samples/02-agents/harness/console/formatters.py | Prevents AttributeError by requiring JSON-decoded arguments to be a dict. |
| python/packages/core/tests/core/test_harness_agent.py | Adds unit tests ensuring tool approval middleware is added/omitted and ordered correctly. |
| python/packages/core/agent_framework/_harness/_agent.py | Installs tool approval middleware by default and exposes new configuration kwargs. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
westey (westey-m)
temporarily deployed
to
integration
June 15, 2026 13:54 — with
GitHub Actions
Inactive
westey (westey-m)
temporarily deployed
to
integration
June 15, 2026 13:54 — with
GitHub Actions
Inactive
Addresses PR review feedback that the parameter name was unclear. The flag toggles the auto/standing tool-approval middleware. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
westey (westey-m)
temporarily deployed
to
integration
June 15, 2026 14:23 — with
GitHub Actions
Inactive
westey (westey-m)
temporarily deployed
to
integration
June 15, 2026 14:23 — with
GitHub Actions
Inactive
Eduard van Valkenburg (eavanvalkenburg)
approved these changes
Jun 15, 2026
westey (westey-m)
enabled auto-merge
June 15, 2026 16:15
Tao Chen (TaoChenOSU)
approved these changes
Jun 15, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Jun 15, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Jun 16, 2026
westey (westey-m)
enabled auto-merge
June 16, 2026 13:24
westey (westey-m)
temporarily deployed
to
integration
June 16, 2026 13:24 — with
GitHub Actions
Inactive
westey (westey-m)
temporarily deployed
to
integration
June 16, 2026 13:24 — with
GitHub Actions
Inactive
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Jun 16, 2026
westey (westey-m)
removed this pull request from the merge queue due to a manual request
Jun 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation and Context
The Python harness (
create_harness_agent) did not include tool approval out of the box, unlike the .NET harness. Agents could invoke approval-required tools without any standing "don't ask again" mechanism, and the console sample's approval prompt only offered approve-once / deny.This change brings the Python harness to parity by integrating the existing
ToolApprovalMiddlewareas a default, batteries-included feature, and surfaces the framework's standing-approval helpers in the console sample. It also fixes a small defensive bug in the sample's tool-call formatter that surfaced while exercising the approval flow.Description
_harness/_agent.py):create_harness_agentnow wiresToolApprovalMiddlewareby default, placed outermost so it intercepts inbound "always approve" responses and outbound approval requests at the caller boundary and its re-invocation loop re-runs user-supplied middleware. Two new keyword arguments:disable_tool_approval(defaultFalse) to opt out.auto_approval_rulesto pass heuristic callbacks that can auto-approve afunction_call, evaluated after standing rules but before prompting the user.AgentSessionat run time.console/observers/tool_approval.py): the approval prompt now offers "Always approve this tool (any arguments)" and "Always approve this tool with these arguments", backed bycreate_always_approve_tool_responseandcreate_always_approve_tool_with_arguments_response.console/formatters.py):FallbackToolFormatter.format_detailnow guards thatjson.loads-parsed arguments are adictbefore iterating, matching the existingget_argument_valuehelper. Previously, function-call arguments that parsed to a non-dict raisedAttributeError: 'str' object has no attribute 'items'during streaming.tests/core/test_harness_agent.pyand documented the feature in the harness sample README.Contribution Checklist