* Add 3 new hosted agent samples: AgentWithTools, AgentWithLocalTools, AgentThreadAndHITL - AgentWithTools: Foundry tools (MCP + code interpreter) via UseFoundryTools - AgentWithLocalTools: Local C# function tool (Seattle hotel search) with AIProjectClient - AgentThreadAndHITL: Human-in-the-loop with ApprovalRequiredAIFunction and thread persistence All samples follow agent-framework conventions (net10.0, AzureCliCredential, CPM disabled). AgentWithTools includes comprehensive README with setup guide and troubleshooting. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add root HostedAgents README, replace test_requests.py with .http, update sample READMEs - Create root README.md with shared prerequisites, Azure AI Foundry setup, troubleshooting, and samples index - Replace test_requests.py with run-requests.http in AgentThreadAndHITL - Add pointer to root README in all 6 sample READMEs - Trim AgentWithTools README to concise style Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix dotnet format issues in AgentWithLocalTools/Program.cs - Add UTF-8 BOM (CHARSET) - Sort System.ClientModel.Primitives import alphabetically (IMPORTS) - Use target-typed new for AIProjectClient (IDE0090) - Add internal accessibility modifier to Hotel record (IDE0040) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: align model names and package versions - Change default model from gpt-4.1-mini to gpt-4o-mini in AgentWithLocalTools (Program.cs, agent.yaml, README.md) to match existing samples - Change README example from gpt-5.2 to gpt-4o-mini in AgentWithTools and root README - Align AgentWithLocalTools package versions with other samples: Azure.AI.AgentServer.AgentFramework beta.6 -> beta.8 Azure.AI.OpenAI 2.8.0-beta.1 -> 2.7.0-beta.2 Microsoft.Extensions.AI.OpenAI 10.2.0-preview -> 10.1.1-preview Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Upgrade new samples to latest package versions - Azure.AI.OpenAI: 2.7.0-beta.2 -> 2.8.0-beta.1 - Microsoft.Extensions.AI.OpenAI: 10.1.1-preview -> 10.3.0 Aligns with AgentWithHostedMCP which uses the latest versions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Pin AgentThreadAndHITL to Microsoft.Extensions.AI.OpenAI 10.1.1 Azure.AI.AgentServer.AgentFramework beta.8 was compiled against Microsoft.Extensions.AI.Abstractions with the single-param FunctionApprovalRequestContent.CreateResponse(bool). Version 10.3.0 changed the signature to include an optional reason parameter, causing a binary incompatibility at runtime. Pin to 10.1.1 until the framework is recompiled against the newer abstractions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2.4 KiB
What this sample demonstrates
This sample demonstrates Human-in-the-Loop (HITL) capabilities with thread persistence. The agent wraps function tools with ApprovalRequiredAIFunction so that every tool invocation requires explicit user approval before execution. Thread state is maintained across requests using InMemoryAgentThreadRepository.
Key features:
- Requiring human approval before executing function calls
- Persisting conversation threads across multiple requests
- Approving or rejecting tool invocations at runtime
For common prerequisites and setup instructions, see the Hosted Agent Samples README.
Prerequisites
Before running this sample, ensure you have:
- .NET 10 SDK installed
- An Azure OpenAI endpoint configured
- A deployment of a chat model (e.g., gpt-4o-mini)
- Azure CLI installed and authenticated (
az login)
Environment Variables
Set the following environment variables:
# Replace with your Azure OpenAI endpoint
$env:AZURE_OPENAI_ENDPOINT="https://your-openai-resource.openai.azure.com/"
# Optional, defaults to gpt-4o-mini
$env:AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini"
How It Works
The sample uses ApprovalRequiredAIFunction to wrap standard AI function tools. When the model decides to call a tool, the wrapper intercepts the invocation and returns a HITL approval request to the caller instead of executing the function immediately.
- The user sends a message (e.g., "What is the weather in Vancouver?")
- The model determines a function call is needed and selects the
GetWeathertool ApprovalRequiredAIFunctionintercepts the call and returns an approval request containing the function name and arguments- The user responds with
approveorreject - If approved, the function executes and the model generates a response using the result
- If rejected, the model generates a response without the function result
Thread persistence is handled by InMemoryAgentThreadRepository, which stores conversation history keyed by conversation.id. This means the HITL flow works across multiple HTTP requests as long as each request includes the same conversation.id.
Note: HITL requires a stable
conversation.idin every request so the agent can correlate the approval response with the original function call. Use therun-requests.httpfile in this directory to test the full approval flow.