.NET: [Feature]: .NET: resumable human approvals for agents used as tools (AsAIFunction)
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
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:
FunctionInvocationProcessorrecords a thrown call withterminate: false, so the model is called again with "Error: Function failed." The function has to return a pause value and setFunctionInvocationContext.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
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de microsoft/agent-framework
-
Python: [Bug]: Out-of-range Cosmos memory search parameters silently disable retrievalPosiblemente ocupada @Lesereingrape la tomó hace 1 día. Abiertopython triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
microsoft/agent-framework#9317 ·
Los mantenedores suelen responder en 1 día
-
Python: [Bug]: A non-positive MCP request timeout silently disables the timeoutPosiblemente ocupada @Lesereingrape la tomó hace 1 día. Abiertopython triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
microsoft/agent-framework#9313 ·
Los mantenedores suelen responder en 1 día
-
Python: [Bug]: Content.from_dict leaves the nested content of image generation and MCP server tool results as plain dictsPosiblemente ocupada @shanto462 la tomó hace 1 día. Abiertopython triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 77/100
microsoft/agent-framework#9303 ·
Los mantenedores suelen responder en 1 día
-
.NET: Python: [Bug]: Two switch-case branches cannot route to the same executor (EdgeDuplicationError)Posiblemente ocupada @shanto462 la tomó hace 1 día. Abierto.NET python triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
microsoft/agent-framework#9297 ·
Los mantenedores suelen responder en 1 día
-
.NET: Proposal: add an llms.txtAbierto.NET python triage
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
microsoft/agent-framework#9092 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de microsoft/agent-framework
Issues similares
-
effort: low prio: low ready
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
digitalfabrik/integreat-cms#4616 ·
Los mantenedores suelen responder en 5 días
-
bug difficulty:2 good first issue help wanted
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
MakazhanAlpamys/Soup#1865 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
FinanceFlash/unvibecode#233 ·
Los mantenedores suelen responder en 1 día
-
area: agents area: docs good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
openapi/gknowledge#23 ·
-
useless-suppression reported for deprecated-* messages that should be exemptPosiblemente ocupada @adityasinha-ghub la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
pylint-dev/pylint#11656 ·
Los mantenedores suelen responder en 1 día