* .NET: Bump Azure.AI.Projects to 2.1.0-beta.2 and add agent-endpoint AsAIAgent path
Bumps Azure.AI.Projects to 2.1.0-beta.2 with the matching transitive pins (Azure.Core 1.55.0, System.ClientModel 1.11.0).
Foundry agent endpoint plumbing:
* FoundryAgent now routes the agent-endpoint constructor through the new GetProjectResponsesClientForAgentEndpoint helper.
* Adds an internal FoundryAgent ctor that takes an existing AIProjectClient plus a parsed agent endpoint so the public extension does not need to construct a second project client.
* Adds public AIProjectClient.AsAIAgent(Uri agentEndpoint, ...) extension. This is the path consumer samples are expected to use for hosted agents because version selection happens server-side.
* Trims the dangling "If you want to construct a FoundryAgent against a project endpoint..." sentence from ParseAgentEndpoint.
Unit tests:
* Four new tests in AzureAIProjectChatClientExtensionsTests cover the AIProjectClient.AsAIAgent(Uri agentEndpoint, ...) overload. 263/263 pass.
Consumer samples (Using-Samples):
* SimpleAgent and SessionFilesClient now read AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_AGENT_NAME (both required, throw on missing), derive the agent endpoint with new Uri($"{projectEndpoint}/agents/{agentName}/endpoint/protocols/openai"), then call aiProjectClient.AsAIAgent(agentEndpoint, ...).
* SessionFilesClient README updated.
Contributor samples (responses/*):
* New HostedContributorRouteExtensions.MapDevTemporaryLocalAgentEndpoint() wildcard route extension so localhost contributor servers accept the per-agent OpenAI endpoint shape the production Hosted runtime exposes.
* All 11 contributor Program.cs files call MapDevTemporaryLocalAgentEndpoint() with a contributor-only warning comment.
* Hosted-Files and Hosted-AzureSearchRag were importing Hosted_Shared_Contributor_Setup but never calling AddDevTemporaryLocalContributorSetup(). Both now call it so HostedSessionIsolationKeyProvider resolves correctly in dev.
* Hosted-AzureSearchRag, Hosted-Files, Hosted-MemoryAgent csprojs drop stale VersionOverride="2.1.0-beta.1" pins.
* Hosted-AzureSearchRag and Hosted-Files csprojs add ProjectReference to Hosted_Shared_Contributor_Setup.
* Hosted-Observability/.dockerignore removed the out/ exclusion that was blocking COPY out/ . in Dockerfile.contributor.
Verified:
* Full solution-scoped build of changed projects: green.
* Scoped CI-parity dotnet format via WSL2 + Docker (mcr.microsoft.com/dotnet/sdk:10.0) over every changed csproj: clean.
* Foundry unit tests: 263/263.
* Contributor docker smoke for 8 hosted samples (publish + docker build + docker run + curl POST to the wildcard route): HTTP 200 / 500 with route matched.
* End-to-end smoke against the real Azure Foundry project with a fresh bearer token: Hosted-Files contributor container served HTTP 200, the agent invoked ListBundledFiles, and returned the expected file name.
* Address PR review: forward pipeline settings; add UTs
- CreateProjectClientOptions also carries RetryPolicy, NetworkTimeout, ClientLoggingOptions, MessageLoggingPolicy (was Transport+UserAgentApplicationId only).
- Make CreateProjectClientOptions internal so tests can verify the copy directly.
- Add AsAIAgent(Uri) UTs covering tools forwarding to inner ChatOptions and null tools handling.
- Add CreateProjectClientOptions UTs covering null caller and full pipeline-settings copy.
Hosted-TextRag
A hosted agent with Retrieval Augmented Generation (RAG) capabilities using TextSearchProvider. The agent grounds its answers in product documentation by running a search before each model invocation, then citing the source in its response.
This sample demonstrates how to add knowledge grounding to a hosted agent without requiring an external search index — using a mock search function that can be replaced with Azure AI Search or any other provider.
Prerequisites
- .NET 10 SDK
- An Azure AI Foundry project with a deployed model (e.g.,
gpt-4o) - Azure CLI logged in (
az login)
Configuration
Copy the template and fill in your project endpoint:
cp .env.example .env
Edit .env and set your Azure AI Foundry project endpoint:
AZURE_AI_PROJECT_ENDPOINT=https://<your-account>.services.ai.azure.com/api/projects/<your-project>
ASPNETCORE_URLS=http://+:8088
ASPNETCORE_ENVIRONMENT=Development
AZURE_AI_MODEL_DEPLOYMENT_NAME=gpt-4o
AZURE_BEARER_TOKEN=
Note:
.envis gitignored. The.env.exampletemplate is checked in as a reference.
Running directly (contributors)
This project uses ProjectReference to build against the local Agent Framework source.
cd dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-TextRag
AGENT_NAME=hosted-text-rag dotnet run
The agent will start on http://localhost:8088.
Test it
Using the Azure Developer CLI:
azd ai agent invoke --local "What is your return policy?"
azd ai agent invoke --local "How long does shipping take?"
azd ai agent invoke --local "How do I clean my tent?"
Or with curl:
curl -X POST http://localhost:8088/responses \
-H "Content-Type: application/json" \
-d '{"input": "What is your return policy?", "model": "hosted-text-rag"}'
Running with Docker
Since this project uses ProjectReference, use Dockerfile.contributor which takes a pre-published output.
1. Publish for the container runtime (Linux Alpine)
dotnet publish -c Debug -f net10.0 -r linux-musl-x64 --self-contained false -o out
2. Build the Docker image
docker build -f Dockerfile.contributor -t hosted-text-rag .
3. Run the container
Generate a bearer token on your host and pass it to the container:
# Generate token (expires in ~1 hour)
export AZURE_BEARER_TOKEN=$(az account get-access-token --resource https://ai.azure.com --query accessToken -o tsv)
# Run with token
docker run --rm -p 8088:8088 \
-e AGENT_NAME=hosted-text-rag \
-e AZURE_BEARER_TOKEN=$AZURE_BEARER_TOKEN \
--env-file .env \
hosted-text-rag
4. Test it
Using the Azure Developer CLI:
azd ai agent invoke --local "What is your return policy?"
How RAG works in this sample
The TextSearchProvider runs a mock search before each model invocation:
| User query contains | Search result injected |
|---|---|
| "return" or "refund" | Contoso Outdoors Return Policy |
| "shipping" | Contoso Outdoors Shipping Guide |
| "tent" or "fabric" | TrailRunner Tent Care Instructions |
The model receives the search results as additional context and cites the source in its response. In production, replace MockSearchAsync with a call to Azure AI Search or your preferred search provider.
NuGet package users
If you are consuming the Agent Framework as a NuGet package (not building from source), use the standard Dockerfile instead of Dockerfile.contributor. See the commented section in HostedTextRag.csproj for the PackageReference alternative.