[dotnet-port-fixes] Gate approval-required Copilot tools#459
[dotnet-port-fixes] Gate approval-required Copilot tools#459michelle-clayton-work wants to merge 4 commits into
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Generated by Go API Consistency Review Agent for #459 · 294.1 AIC · ⌖ 13 AIC · ⊞ 27.1K
|
@copilot address PR feedback and resolve conversations once addressed |
Co-authored-by: michelle-clayton-work <262183035+michelle-clayton-work@users.noreply.github.com>
Co-authored-by: michelle-clayton-work <262183035+michelle-clayton-work@users.noreply.github.com>
Addressed the PR feedback in commit |
There was a problem hiding this comment.
Pull request overview
This PR updates the Copilot provider’s per-run session configuration assembly to automatically gate “approval-required” Copilot tools by installing a default Hooks.OnPreToolUse hook (when the caller hasn’t supplied one), preventing unintended execution without an explicit approval request path.
Changes:
- Install a default
OnPreToolUsehook that returnsaskfor approval-required tools when no caller hook is provided. - Clone session tool and hook state during session/resume config construction to avoid mutating the caller’s
SessionConfig. - Add internal tests covering create/resume gating, preservation of caller hooks, non-mutation guarantees, and warning emission when auto-gating is skipped.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| provider/copilotprovider/copilot.go | Adds approval-gating hook installation, warning log when caller hook bypasses auto-gating, and clones tool slices to prevent config mutation. |
| provider/copilotprovider/copilot_internal_test.go | Adds focused internal tests validating approval gating behavior, cloning/non-mutation, caller hook preservation, and warning logging. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Cross-Repo Consistency Review ✅This PR is a faithful port of upstream .NET PR #6674 and is semantically aligned across all three SDK implementations.
The use of No cross-repo consistency issues found.
|
| var names map[string]struct{} | ||
| approvalRequiredNames := func() map[string]struct{} { | ||
| if names == nil { | ||
| names = approvalRequiredToolNames(tools) | ||
| } | ||
| return names | ||
| } |
There was a problem hiding this comment.
This is confusing--implementation suggests that lazy init is useful, but approvalRequiredNames is only ever called once. It looks like this block could be entirely removed
| var names map[string]struct{} | |
| approvalRequiredNames := func() map[string]struct{} { | |
| if names == nil { | |
| names = approvalRequiredToolNames(tools) | |
| } | |
| return names | |
| } |
then approvalRequiredToolNames(tools) could be called in each of the call sites without losing anything and names := approvalRequiredToolNames(tools) would be more obvious.
| if tl.Name == "" || tl.SkipPermission { | ||
| continue | ||
| } | ||
| if names == nil { | ||
| names = make(map[string]struct{}) | ||
| } | ||
| names[tl.Name] = struct{}{} |
There was a problem hiding this comment.
According to Copilot, this is wrong, but I don't have the context to easily confirm/refute:
The Go port detects approval-required tools by checking
!SkipPermissioninapprovalRequiredToolNames, but the .NET source (PR #6674) instead detects them via an explicitApprovalRequiredAIFunctionmarker that is independent ofSkipPermission; becauseSkipPermissiondefaults tofalse, any caller-suppliedSessionConfig.Toolsthat didn't set it get silently"ask"-gated even though the caller never marked them approval-required, and conversely a genuinely approval-required tool withSkipPermission = truewould be wrongly excluded from gating (the opposite of .NET, where such a tool is still gated) — a semantic inversion the port's own test wrongly encodes by gating a barecopilot.Tool{Name: "dangerous"}.
Summary
Align
provider/copilotproviderwith the .NET Copilot approval fix by installing a defaultOnPreToolUsehook for approval-required tools when the caller has not provided one. The hook returnsaskfor tools that require approval, preserves caller-suppliedHooks.OnPreToolUse, and clones tool/hook state so per-run session assembly does not mutate the caller'sSessionConfig.This also adds a developer warning when a caller-supplied
Hooks.OnPreToolUseis present alongside approval-required tools, indicating those tools will not be auto-gated and the custom hook is responsible for approval handling.Ported .NET PRs
d5c5fb9d3de3a19c0f55d958464646dfefdb59e3(https://github.com/microsoft/agent-framework/commit/d5c5fb9d3de3a19c0f55d958464646dfefdb59e3)Breaking Changes
No.
Tests and Examples
go test ./provider/copilotprovider -count=1go test ./provider/... -count=1go test ./... -count=1OnPreToolUsehooks, non-mutation of sourceSessionConfig, and warning emission when custom hooks bypass auto-gating.Notes
Hooks.OnPreToolUseauthoritative and now emits a warning when approval-required tools are present but auto-gating is skipped due to a custom hook.> Generated by .NET to Go Fixes and Test Porting Agent · 953.8 AIC · ⌖ 32.3 AIC · ⊞ 21.7K · ◷
Closes #456