Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Microsoft Agent framework Content Function Approval Request Pattern

From Leeroopedia
Knowledge Sources
Domains Agent_Architecture, Safety, Human_in_the_Loop
Type Pattern Doc (user-defined interface, not a library API)
Last Updated 2026-02-11 17:00 GMT

Overview

Implementation pattern for presenting function approval requests to users, enabling a human-in-the-loop safety gate before the agent executes tool calls. This is a user-defined interface pattern built on top of the Content class in the Microsoft Agent Framework.

Description

When the agent framework determines that a function call requires human approval, it wraps the pending call in a Content object of type "function_approval_request". The application developer is responsible for iterating these requests, extracting the tool name and arguments from the nested function_call field, presenting them to the user through an application-specific UI, and submitting the user's decision back to the framework.

The pattern spans two framework components:

  • Content class (_types.py:L458-509): Defines the data structure with fields id, function_call, user_input_request, and approved.
  • AgentResponse / AgentResponseUpdate (_types.py:L2341-2348, L2549-2551): Provide the user_input_requests property that filters Content items where user_input_request is True.

Usage

Import the Content class and access the approval fields after an agent run. Iterate result.user_input_requests to find all pending approvals, then call request.to_function_approval_response(approved=...) to submit each decision.

Code Reference

Source Location

  • Repository: agent-framework
  • File: python/packages/core/agent_framework/_types.py
  • Lines: L458-509 (Content class definition), L971-989 (from_function_approval_request factory), L1013-1029 (to_function_approval_response conversion)

Key Factory Method

@classmethod
def from_function_approval_request(
    cls: type[ContentT],
    id: str,
    function_call: Content,
    *,
    annotations: Sequence[Annotation] | None = None,
    additional_properties: MutableMapping[str, Any] | None = None,
    raw_representation: Any = None,
) -> ContentT:
    """Create function approval request content."""
    return cls(
        "function_approval_request",
        id=id,
        function_call=function_call,
        user_input_request=True,
        annotations=annotations,
        additional_properties=additional_properties,
        raw_representation=raw_representation,
    )

Import

from agent_framework import Content

I/O Contract

Key Fields (Content with type="function_approval_request")

Name Type Required Description
id str Yes Unique identifier for the approval request. Used to correlate the user's response back to the correct pending function call. Typically derived from call_id of the original function call.
function_call Content Yes Mapping: the arguments the LLM wants to pass).
user_input_request bool Yes Always True for approval requests. Signals the framework (and the AgentExecutor workflow) to pause execution and emit a request_info event.
type Literal["function_approval_request"] Yes The content type discriminator. Must be "function_approval_request".

Nested function_call Content Fields

Name Type Description
name str The name of the tool/function the LLM wants to invoke.
arguments Mapping[str, Any] The arguments the LLM wants to pass to the tool. May be a JSON string or a parsed mapping.
call_id str The unique identifier for this specific function call invocation.

Response Conversion

Method Input Output Description
to_function_approval_response(approved) bool Content (type="function_approval_response") Converts the approval request into an approval response with the user's decision. Preserves id, function_call, and annotations.

Interface Specification

# Pattern: Present each approval request to the user
for request in result.user_input_requests:
    # Extract tool information
    tool_name: str = request.function_call.name
    tool_args: str | Mapping = request.function_call.arguments
    request_id: str = request.id

    # Display to user (application-specific)
    print(f"Agent wants to call: {tool_name}")
    print(f"With arguments: {tool_args}")
    approved: bool = get_user_decision()  # Your UI logic

Usage Examples

Basic CLI Approval Flow

from agent_framework import Agent, Content

agent = Agent(
    client=client,
    tools=[my_sensitive_tool],
)

result = await agent.run("Delete the temporary files")

# Check for pending approval requests
for request in result.user_input_requests:
    tool_name = request.function_call.name
    tool_args = request.function_call.arguments

    print(f"Tool: {tool_name}")
    print(f"Args: {tool_args}")
    user_choice = input("Approve this call? [y/n]: ").strip().lower()

    # Convert approval request to response
    response = request.to_function_approval_response(approved=(user_choice == "y"))

Streaming Approval Flow

from agent_framework import Agent, Content

async for update in agent.run("Perform database migration", stream=True):
    # Process text updates
    if update.text:
        print(update.text, end="", flush=True)

    # Handle approval requests as they arrive during streaming
    for request in update.user_input_requests:
        tool_name = request.function_call.name
        tool_args = request.function_call.arguments
        print(f"\n[APPROVAL NEEDED] {tool_name}({tool_args})")
        approved = await async_get_user_decision()
        response = request.to_function_approval_response(approved=approved)

Framework Internal: How Approval Requests Are Created

# From agent_framework/_tools.py (internal framework logic, not user code)
# When approval_needed is True for function calls:
[
    Content.from_function_approval_request(
        id=fcc.call_id,
        function_call=fcc,
    )
    for fcc in function_calls
    if fcc.type == "function_call"
]

Data Flow

The approval request pattern follows this sequence:

  1. The LLM returns one or more function_call Content objects in its response.
  2. The framework's function invocation layer checks if approval is required (configured via FunctionInvocationConfiguration).
  3. If approval is needed, each function_call Content is wrapped in a function_approval_request Content via Content.from_function_approval_request().
  4. The user_input_request=True flag causes the AgentExecutor to emit a request_info event and pause the workflow.
  5. The AgentResponse.user_input_requests (or AgentResponseUpdate.user_input_requests) property exposes these to the application.
  6. The application presents each request to the user and collects a decision.
  7. The application calls request.to_function_approval_response(approved=True/False) to create the response Content.
  8. The response is submitted back to the framework, which either executes or skips the function accordingly.

Related Pages

Implements Principle

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment