Repository navigation
.NET: [Feature Request] Function Invocation Middleware for Nested Tools (HITL Support) #4158
Copy link
Copy link
Open
Open
Copy link
Labels
.NETUsage: [Issues, PRs], Target: .NetUsage: [Issues, PRs], Target: .Net
Description
Use Case
We need to intercept MCP tool invocations within nested agents (e.g., FinancialAgent called via handoff from TriageAgent) to implement Human-in-the-Loop (HITL) approval workflows.
Our application requires user confirmation before executing write operations (create transactions, update budgets, delete records). The workflow involves:
- User sends message to TriageAgent
- TriageAgent hands off to FinancialAgent (or other specialized agent)
- FinancialAgent invokes MCP tools (e.g.,
register_expense) - Before tool execution, we need to suspend workflow and request user approval
- Resume workflow after approval with same context
Current Limitation
response.Messagesonly exposes top-level handoffs (e.g.,handoff_to_1)- MCP tool invocations within handoffed agents are hidden from the response
- No callback API available to intercept tool execution before it occurs
- Documentation references
CallbackMiddleware<AgentFunctionInvocationCallbackContext>but classes don't exist in preview
Evidence from our investigation:
// What we receive in response.Messages:
FunctionCallContent { Name: "handoff_to_1" } // ❌ Handoff, not tool name
// What we need to intercept:
FunctionCallContent { Name: "register_expense" } // ✅ Actual MCP toolPackage version tested: Microsoft.Agents.AI 1.0.0-preview.260212.1
Requested API
1. Function Invocation Callback Middleware
public class AgentFunctionInvocationCallbackContext
{
public AIFunction Function { get; set; }
public AIFunctionArguments Arguments { get; set; }
public bool Terminate { get; set; } // Suspend workflow before execution
}
public abstract class CallbackMiddleware<TContext>
{
public abstract Task OnProcessAsync(
TContext context,
Func<TContext, Task> next,
CancellationToken cancellationToken);
}2. Expose Nested Tool Calls in Response
Either:
- Option A: Include nested tool invocations in
response.Messages(e.g.,register_expensealongsidehandoff_to_1) - Option B: Invoke callbacks BEFORE tool execution (even for nested tools within handoffs)
3. Checkpoint Resumption with Context
- Resume workflow from suspended state after approval
- Restore exact context at suspension point
- Execute approved tool with original arguments
Workaround Impact
Without this API:
- ❌ ALL write operations execute without user confirmation
- ❌ Violates GDPR/LGPD compliance (no explicit consent for data mutations)
- ❌ Cannot implement HITL workflows for 22 critical operations
- ❌ Users may create accidental transactions/deletions
Business Impact: Cannot deploy to production without HITL compliance.
Related Documentation
- ADR-0007 mentions callback patterns: https://github.com/microsoft/agent-framework/blob/main/docs/decisions/0007-agent-filtering-middleware.md
.UseCallbacks()exists but requiresCallbackMiddleware<T>(not available)
Proposed Timeline
This is a blocking issue for production deployment. We have prepared code for callback implementation and are ready to integrate as soon as the API is available.
Thank you for considering this feature request!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
.NETUsage: [Issues, PRs], Target: .NetUsage: [Issues, PRs], Target: .Net
Type
Projects
- StatusShow more project fieldsBacklog
Activity
[-][Feature Request] Function Invocation Middleware for Nested Tools (HITL Support)[/-][+].NET: [Feature Request] Function Invocation Middleware for Nested Tools (HITL Support)[/+]arturteplov commentedon Oct 18, 2026
LI (@ktz03) How are you currently handling MCP tool permissions across nested agent handoffs, particularly when execution needs to pause for approval and resume with the same context?
ktz03 commentedon Oct 19, 2026
Artur Teplov (@arturteplov) I’d use the current .NET approval sample as a starting point: it resumes with the matching approval response and the same
AgentSession. I haven’t checked the nested MCP handoff/restart case yet. Which SDK/version and handoff setup are you using, and should the approval survive a process restart? We can work through a small example together.arturteplov commentedon Oct 20, 2026
LI (@ktz03) I looked through the sample. I’d like to extend it to nested MCP tool approvals and test whether authorization and context survive a process restart.
I haven’t picked an SDK version yet. Which version and persistence approach would you use?
Happy to put together a minimal repro.
ktz03 commentedon Oct 20, 2026
Artur Teplov (@arturteplov) I'd pin the repro to .NET 10 and Agent Framework 1.25.0, using that release's session serialization sample with a local JSON file first.
I'd save each participating agent's session and the app's pending-request correlation, then reload the sessions and recreate the same tool bindings and MCP authentication after restart; session persistence and human tool approval do not preserve MCP credentials or server-side authorization.
I haven't verified that nested restart path, and the same-version approval sample notes that unanswered requests are rejected on the next run, so the matching decision needs to accompany continuation.
Could you share a one-parent/one-child/one-tool repro with the model provider and MCP transport pinned; I'll check the approval/session routing against the no-restart control, with context preserved, no tool execution before approval or after rejection, and one execution after approval as the initial checks?