Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

.NET: [Feature]: .NET: resumable human approvals for agents used as tools (AsAIFunction)

Abierto
#9,130 0 comentarios 1 reacción 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@rogerbarreto ya está trabajando en esto.

Desde el 7/10/2026.

Evaluación

Este issue todavía no se ha evaluado.

Descripción

.NET agents
Description

Following up on #4963, where the maintainers suggested opening a separate feature issue for resumable nested-agent approvals.

Problem. A primary agent that delegates subtasks to other agents as tools (agent-as-tools, AIAgent.AsAIFunction) cannot complete a subtask whose inner tool needs human approval (ApprovalRequiredAIFunction). The inner agent's ToolApprovalRequestContent never reaches the caller, so the delegated call can only fail. Handoff and group chat workflows do surface approvals, but they change the model: control and the full conversation pass to the other agent, and the primary agent no longer delegates a subtask and continues with its result. For hosts where a primary agent coordinates several specialist agents over many turns, and the specialists see only what they are sent, call and return with a human approval in the middle is the missing combination.

Expected behavior. When an agent invoked as a tool pauses for approval, the primary agent's response carries an approval request the caller can answer with the existing approval flow. On approval, the delegated call resumes the inner agent with the decision and returns its result to the primary agent's tool loop. On rejection, the inner tool never runs.

What we found prototyping it on Microsoft.Agents.AI 1.16 / Microsoft.Extensions.AI 10.8 with public APIs only (UseProvidedChatClientAsIs, UseApprovalResponseBinding, UseApprovalNotRequiredFunctionBypassing, UseFunctionInvocation):

  • A chat-client step between approval-response binding and the approval-not-required bypass can turn a paused delegated call into an approval request for the same call id. Function invocation then re-invokes the delegated function on approval, and binding validates the response.
  • Placement is critical. Below the bypass, the bypass removes the request (the delegating function needs no approval of its own) and re-injects it as approved on the next turn, so the inner tool runs with no human decision.
  • A function cannot stop the loop by throwing: FunctionInvocationProcessor records a thrown call with terminate: false, so the model is called again with "Error: Function failed." The function has to return a pause value and set FunctionInvocationContext.Terminate.
  • Other calls in the same batch need a synthesized result once the loop stops, or the history holds a call with no result.
  • Opting out of the default stack also drops the internal deferred telemetry slot, so a custom stack must add its own OpenTelemetry client below function invocation.

Each of these is easy to get wrong in host code, and the placement one fails open. A framework-owned option would close that risk.

Possible shape. An opt-in on AsAIFunction (or AIFunctionFactoryOptions), or a public decorator for custom stacks, that propagates an inner agent's approval requests and resumes the inner agent with the caller's decision. The inner agent's paused state would be held in its session, which the caller already passes to AsAIFunction.

Alternatives considered. Handoff or group chat workflows (they change ownership and context, as above). Failing closed per #4963 (safe, but agent-as-tools then cannot take gated actions at all).

Code Sample
AIAgent specialist = new ChatClientAgent(chatClient, new ChatClientAgentOptions
{
    Name = "specialist",
    ChatOptions = new() { Tools = [new ApprovalRequiredAIFunction(AIFunctionFactory.Create(ProcessRefund))] },
});

AIAgent primary = new ChatClientAgent(chatClient, new ChatClientAgentOptions
{
    Name = "primary",
    // Hypothetical option, shown as the desired shape; it does not exist today.
    ChatOptions = new() { Tools = [specialist.AsAIFunction(new() { PropagateApprovals = true }, specialistSession)] },
});

var response = await primary.RunAsync("Refund order 1234", session);
var request = response.Messages.SelectMany(m => m.Contents).OfType<ToolApprovalRequestContent>().Single();
var resumed = await primary.RunAsync(new ChatMessage(ChatRole.User, [request.CreateResponse(approved: true)]), session);
Language/SDK

.NET

Lenguaje dominante
Python
Estrellas
14k
Forks
2.5k
Merge medio
2 d 2 h
PR fusionados (30 d)
389

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de microsoft/agent-framework

Todos los issues de microsoft/agent-framework

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.