Files
Roger Barreto de791fb8a9 .Net: Add additional Hosted Agent Samples (#4325)
* 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>
2026-03-02 10:56:28 +00:00

47 lines
2.4 KiB
Markdown

# 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](../README.md).
## Prerequisites
Before running this sample, ensure you have:
1. .NET 10 SDK installed
2. An Azure OpenAI endpoint configured
3. A deployment of a chat model (e.g., gpt-4o-mini)
4. Azure CLI installed and authenticated (`az login`)
## Environment Variables
Set the following environment variables:
```powershell
# 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.
1. The user sends a message (e.g., "What is the weather in Vancouver?")
2. The model determines a function call is needed and selects the `GetWeather` tool
3. `ApprovalRequiredAIFunction` intercepts the call and returns an approval request containing the function name and arguments
4. The user responds with `approve` or `reject`
5. If approved, the function executes and the model generates a response using the result
6. 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.id` in every request so the agent can correlate the approval response with the original function call. Use the `run-requests.http` file in this directory to test the full approval flow.