Files
Roger Barreto f45fc7d402 .NET: [Breaking] Update Foundry Agents for Responses API (#4502)
* Stage

* Add FoundryAgentClient, model param, chatClientFactory, and RAPI samples

- Add model parameter to FoundryAgentClient simple constructor
- Add chatClientFactory parameter to both constructors
- Switch to OpenAI.GetProjectResponsesClientForModel for direct Responses API usage
- Add FoundryAgents-RAPI samples (Step01 Basics, Step02 Multiturn, Step03 FunctionTools)
- Add solution folder entry for FoundryAgents-RAPI samples

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add auto-discovery constructor and simplify RAPI samples

- Add FoundryAgentClient constructor that reads AZURE_AI_PROJECT_ENDPOINT and
  AZURE_AI_MODEL_DEPLOYMENT_NAME from environment variables with DefaultAzureCredential
- Simplify RAPI samples to use auto-discovery (no env var or credential code)
- Remove Azure.Identity direct references from sample csproj files
- Update READMEs to document environment variable requirements

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add remaining RAPI samples (Step04-Step12)

- Step04: Function tools with human-in-the-loop approvals
- Step05: Structured output with typed responses
- Step06: Persisted conversations with session serialization
- Step07: Observability with OpenTelemetry
- Step08: Dependency injection with hosted service
- Step10: Image multi-modality
- Step11: Agent as function tool (agent composition)
- Step12: Middleware (PII, guardrails, function logging, HITL approval)
- Update solution file and folder README with all new samples

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add all RAPI samples (Step09-Step23) and switch to AzureCliCredential

- Step09: MCP client as tools (GitHub server via stdio)
- Step13: Plugins with dependency injection
- Step14: Code Interpreter tool
- Step15: Computer Use tool with screenshot simulation
- Step16: File Search with vector stores
- Step17: OpenAPI tools (REST Countries API)
- Step18: Bing Custom Search
- Step19: SharePoint grounding
- Step20: Microsoft Fabric
- Step21: Web Search with citations
- Step22: Memory Search with multi-turn conversations
- Step23: Local MCP via HTTP (Microsoft Learn)
- Switch all samples (Step04-Step12) to use AzureCliCredential with env vars
- Update solution file and README with all 23 samples
- All 23 samples build successfully, tested Step05/06/11/13/21

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Switch Step01-03 samples to AzureCliCredential for consistency

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Clarify connection ID format in SharePoint and Fabric READMEs

Document that SHAREPOINT_PROJECT_CONNECTION_ID and FABRIC_PROJECT_CONNECTION_ID
should use the connection name (e.g., 'SharepointTestTool'), not the full ARM
resource URI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Normalize env vars, fix structured output, update READMEs with connection ID formats

- Normalize AZURE_FOUNDRY_PROJECT_* env vars to AZURE_AI_PROJECT_ENDPOINT / AZURE_AI_MODEL_DEPLOYMENT_NAME across all samples (Steps 18-22 READMEs + Steps 19-20 Program.cs)
- Fix RAPI Step05 StructuredOutput to use full constructor with ResponseFormat for streaming JSON
- Update Deep Research sample to use AzureCliCredential
- Enrich Bing Grounding README with full ARM resource URI format
- Fix Bing Custom Search README env var mismatch (BING_CUSTOM_SEARCH_* -> AZURE_AI_CUSTOM_SEARCH_*)
- Add finding instructions for connection ID and instance name in Bing Custom Search READMEs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Refactor memory samples and switch to DefaultAzureCredential

- Refactor RAPI Step22 MemorySearch: extract store setup to EnsureMemoryStoreAsync local function
- Refactor non-RAPI Step22 MemorySearch: same pattern with explicit memory lifecycle
- Set UpdateDelay=0 on MemoryUpdateOptions and MemorySearchPreviewTool for faster ingestion
- Use WaitForMemoriesUpdateAsync with 500ms polling interval
- Switch Step19 SharePoint, Step20 Fabric, Step22 MemorySearch (both) to DefaultAzureCredential
- Remove SearchOptions from MemorySearchPreviewTool (causes unknown parameter error)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Switch all RAPI samples to DefaultAzureCredential and format

- Replace AzureCliCredential with DefaultAzureCredential across all 20 RAPI samples
- Run dotnet format on all RAPI and non-RAPI Foundry samples
- AzureAI unit tests: 341 passed (net10.0 + net472)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Rename to Microsoft Foundry, add metadata, rename RAPI folder

- Replace 'Azure AI Foundry' / 'Azure Foundry' with 'Microsoft Foundry' in all docs, comments, and XML docs
- Update FoundryAgentClient metadata provider name to 'microsoft.foundry'
- Rename FoundryAgents-RAPI folder to FoundryResponseAgents
- Rewrite FoundryResponseAgents README with comparison table vs Foundry Agents
- Update slnx and parent README with new folder references

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR review: simplify sample comments and fix DeepResearch credential

- Remove 'no server-side agent' and 'Responses API directly' phrasing from comments
- Simplify to 'Create a FoundryAgentClient' per review feedback
- Switch Agent_Step15_DeepResearch to DefaultAzureCredential

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Restore full DefaultAzureCredential warning comment in DeepResearch sample

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add ADR 0020: Foundry agent type naming convention

Proposes naming options for a new MAF type wrapping versioned
Foundry agents (Prompt, ContainerApp, Hosted, Workflow) to
distinguish from the existing FoundryResponsesAgent (RAPI path).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Simplify FoundryResponsesAgent samples with env-var constructors and rename folders

- Add env-var constructors to FoundryResponsesAgent (simple + options-based)
- Fix Constructor 1 model optionality (no longer throws on missing AZURE_AI_MODEL_DEPLOYMENT_NAME)
- Add ApplyModelDeploymentFallback helper for options-based constructor
- Update all 23 FoundryResponseAgents samples to remove Environment.GetEnvironmentVariable boilerplate
- Condense 6 simple samples to one-liner constructor calls
- Add XML doc remarks about auto-resolved parameters on all constructors
- Rename FoundryAgents -> FoundryVersionedAgents (server-side, versioned)
- Rename FoundryResponseAgents -> FoundryAgents (now the default path forward)
- Update .slnx and README cross-references for new folder names

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add FoundryAITool factory, rename RAPI folders, and clean up references

- Create FoundryAITool static factory class with 17 methods wrapping AgentTool.Create* and ResponseTool.Create* into AITool returns
- Rename 23 FoundryAgentsRAPI_* subfolders to FoundryAgents_* (drop RAPI prefix)
- Rename .csproj files and update .slnx references accordingly
- Update 12 samples (6 FoundryAgents + 6 FoundryVersionedAgents) to use FoundryAITool
- Replace all FoundryResponsesAgent references with FoundryAgent in comments and READMEs
- Update sample READMEs to reference FoundryAITool methods

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Rename FoundryVersionedAgents subfolders from FoundryAgents_* to FoundryVersionedAgents_*

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add FoundryVersionedAgent class and refactor extension method internals

- Create FoundryVersionedAgent with private ctor and async static factory methods
  (CreateAIAgentAsync/GetAIAgentAsync) with env-var and explicit endpoint tiers
- Extract shared internal helpers from AzureAIProjectChatClientExtensions:
  CreateChatClientAgent, CreateAgentVersionFromOptionsAsync,
  CreateAgentVersionWithProtocolAsync (tools overload),
  CreateChatClientAgentOptions, GetAgentRecordByNameAsync, ThrowIfInvalidAgentName
- Extension methods now delegate to shared internal helpers
- All 49 existing samples continue to build successfully

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add CreateConversationSessionAsync, DeleteAIAgentAsync, auto-resolve model, simplify samples

- Add CreateConversationSessionAsync to FoundryAgent and FoundryVersionedAgent
  (returns ChatClientAgentSession, creates server-side conversation + session in one call)
- Add DeleteAIAgentAsync static method to FoundryVersionedAgent
- Make model parameter optional in env-var factory overloads (auto-resolves from
  AZURE_AI_MODEL_DEPLOYMENT_NAME)
- Update all FoundryVersionedAgents samples to use DeleteAIAgentAsync
- Remove deploymentName env var from samples where only used for model parameter
- Use CreateConversationSessionAsync in Step02_MultiturnConversation
- Use explicit types instead of var for agent/session variables
- All 49 samples build successfully

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove manual AIProjectClient construction from FoundryVersionedAgents samples

- Replace manual AIProjectClient construction with GetService<AIProjectClient>()
  from the FoundryVersionedAgent in all dual-option and tool-specific samples
- Remove AZURE_AI_PROJECT_ENDPOINT env var reads from updated samples
- Remove Azure.Identity usings where no longer needed
- Only Step01.1, Step01.2, Eval_Step01 retain manual construction (pedagogical samples)
- All 49 samples build successfully

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Replace aiProjectClient extension calls with FoundryVersionedAgent factories in all samples

- Replace aiProjectClient.CreateAIAgentAsync with FoundryVersionedAgent.CreateAIAgentAsync
  in Option 2 (Native SDK) paths across Steps 14-21
- Replace aiProjectClient.Agents.DeleteAgentAsync with FoundryVersionedAgent.DeleteAIAgentAsync
- Remove unused AIProjectClient variables and using directives
- Only Step01.1, Step01.2, Eval_Step01 retain direct AIProjectClient usage (pedagogical)
- Step16, Step22 use GetService<AIProjectClient>() for file/memory operations

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove unused using directives from Step01.2, Step09, Eval_Step02

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update ADR 0020 with accepted decision: Option 6

- Add Option 6 detailing FoundryAgent, FoundryVersionedAgent, FoundryAITool,
  env-var auto-discovery, and self-contained factory patterns
- Mark decision as accepted with rationale
- Update current state and metadata sections

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update Step01 basics samples to use FoundryVersionedAgent factories

- Step01.1: Replace manual AIProjectClient/AsAIAgent with FoundryVersionedAgent.CreateAIAgentAsync/GetAIAgentAsync/DeleteAIAgentAsync
- Step01.2: Replace manual AIProjectClient with FoundryVersionedAgent.CreateAIAgentAsync/DeleteAIAgentAsync
- Remove env var boilerplate and Azure.Identity dependency

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add DeleteAIAgentVersionAsync to FoundryVersionedAgent

- DeleteAIAgentAsync: deletes the agent and all its versions (existing)
- DeleteAIAgentVersionAsync: deletes only the specific version associated with the agent instance
- Internally delegates to Agents.DeleteAgentAsync vs Agents.DeleteAgentVersionAsync

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix cleanup comments: DeleteAIAgentAsync deletes the agent and all its versions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update all FoundryVersionedAgents READMEs for FoundryVersionedAgent and auto-discovery

- Rewrite main README with FoundryVersionedAgent usage, auto-discovery table, code example
- Fix sample table links from FoundryAgents_Step* to FoundryVersionedAgents_Step*
- Add FoundryAITool references in tool-specific sample descriptions
- Update individual READMEs: fix stale paths, add auto-discovery note after env var blocks
- Update tool references: AgentTool/ResponseTool -> FoundryAITool
- Update parent 02-agents/README.md with FoundryVersionedAgent description

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Revert unrelated AGUI and Hosting.OpenAI formatting changes to main

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove env-var auto-discovery, add AsAIAgent, mark extensions Obsolete

- Remove 2 env-var constructors from FoundryAgent (keep explicit endpoint ctors)
- Remove 5 env-var factory methods from FoundryVersionedAgent (keep explicit ones)
- Add 3 AsAIAgent static methods to FoundryVersionedAgent (AgentVersion/AgentRecord/AgentReference)
- Mark all 8 AIProjectClient extension methods as [Obsolete] pointing to FoundryVersionedAgent
- Remove ApplyModelDeploymentFallback, env var constants, Azure.Identity usings from source

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update all samples to use explicit endpoint, credential, and model parameters

- Add explicit Environment.GetEnvironmentVariable reads for AZURE_AI_PROJECT_ENDPOINT
  and AZURE_AI_MODEL_DEPLOYMENT_NAME to all 48 sample files
- Pass new Uri(endpoint), new DefaultAzureCredential(), deploymentName to
  FoundryAgent constructors and FoundryVersionedAgent factory methods
- Add using Azure.Identity where missing
- Matches repo-wide pattern used by other non-Foundry samples
- All 49 samples build successfully

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Migrate remaining samples and source from obsoleted extension methods

- Migrate AgentProviders, AgentWithRAG, AgentWithMemory, HostedWorkflow samples to FoundryVersionedAgent
- Migrate AzureAgentProvider.cs to FoundryVersionedAgent.AsAIAgent
- Migrate AzureAIProjectChatClientTests.cs to FoundryVersionedAgent.GetAIAgentAsync
- Remove pragma suppressions from migrated files

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add unit tests for FoundryAgent and FoundryVersionedAgent

- FoundryAgentTests.cs: 14 tests covering constructors, validation,
  properties, metadata, GetService, chat client factory, user-agent header
- FoundryVersionedAgentTests.cs: 31 tests covering CreateAIAgentAsync,
  GetAIAgentAsync, AsAIAgent (3 overloads), DeleteAIAgentAsync,
  DeleteAIAgentVersionAsync, validation, invalid names, metadata, GetService

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Finalize Foundry agent migration

Align FoundryAgent and FoundryVersionedAgent samples, docs, and tests with the explicit configuration model, clean up stale README guidance, and fix AzureAI unit test validation/build issues.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Apply formatter cleanup after validation

Capture the dotnet format follow-up changes produced during branch validation so the committed state matches the successfully built and tested branch.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add integration tests for FoundryAgent and FoundryVersionedAgent

Mark old AIProjectClient extension-method integration tests as obsolete and add new integration test suites for both FoundryAgent (Responses API) and FoundryVersionedAgent (versioned agents). All 71 non-skipped tests pass against the live Foundry service.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update ADR 0020 with test coverage details

Add integration test coverage note to the Current State section of ADR 0020.

* Simplify Foundry agents and validate moved samples

* Rename FoundryAgent integration tests to ResponsesAgent

The test classes exercise the non-versioned Responses path via
AIProjectClient.AsAIAgent(), not the removed FoundryAgent wrapper type.
Rename files and class names to reflect the actual test surface.

* Update documentation for ChatClientAgent usage

Added example usage of ChatClientAgent with JokerAgent.

* Refactor ChatClientAgent instantiation for clarity

* Revise agent type naming and usage examples

Updated documentation to reflect changes in agent creation methods and added examples for using `ChatClientAgent`.

* Fix Azure SDK namespace migration after rebase

Update Azure.AI.Projects.OpenAI references to Azure.AI.Projects.Agents
and Azure.AI.Extensions.OpenAI to match Azure.AI.Projects 2.0.0-beta.2.

- Replace deprecated namespace across samples, tests, and src
- Fix renamed types: OpenAPIFunctionDefinition -> OpenApiFunctionDefinition,
  BingCustomSearchToolParameters -> BingCustomSearchToolOptions,
  BrowserAutomationToolParameters -> BrowserAutomationToolOptions
- Fix API changes: AgentRecord.Versions -> GetLatestVersion(),
  ResponsesClient constructor, FunctionApprovalRequestContent ->
  ToolApprovalRequestContent
- Apply dotnet format

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address merge markers

* Replace obsolete GetAIAgentAsync with AsAIAgent in samples

Switch Agent_Step07_AsMcpTool and A2AServer to use the non-obsolete
PersistentAgentsClient.AsAIAgent(PersistentAgent) extension instead
of the deprecated GetAIAgentAsync, fixing CS0618 build errors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix broken markdown links in Responses sample READMEs

Replace stale ChatClientAgents_Step* folder references with the
correct Agent_Step* names across all Responses sample READMEs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix format errors and address PR review comments

- Fix charset and remove unused using in AzureAIProjectResponsesChatClient
- Fix doc comment tags (code -> c) in FoundryAITool
- Fix stray period in LocalMCP sample comment
- Fix grammar in FoundryMemoryProvider xmldoc
- Fix AIProjectClientAgentRunStreamingConversationTests base class

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Apply dotnet format fixes to PR-changed files

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix build errors from format pass and apply naming conventions

- Fix static call to CreateSessionAsync in Step02 samples and extension tests
- Use expression-bodied lambda in FoundryMemoryProvider (RCS1021)
- Apply PascalCase naming to const fields in ResponsesAgentExtensionCreateTests (IDE1006)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Introduce FoundryAgent sealed type and update AsAIAgent extensions

- Add FoundryAgent sealed class wrapping ChatClientAgent with:
  - Public ctors: (projectEndpoint, credential, model, instructions) and (agentEndpoint, credential)
  - Internal ctor: (AIProjectClient, ChatClientAgent) for extension use
  - CreateConversationSessionAsync() for server-side conversations
  - GetService<ChatClientAgent>() and GetService<AIProjectClient>()
  - MEAI user-agent policy on internally-created AIProjectClient
- Change all AsAIAgent extension return types from ChatClientAgent to FoundryAgent
- Update all samples and tests to use FoundryAgent type
- Add 16 FoundryAgentTests covering ctors, GetService, UserAgent, RunAsync
- Fix pre-existing Agent_Step12_Plugins build error

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Collapse sample folders and add FoundryAgent_Step01 sample

- Move all Responses/* samples up to AgentsWithFoundry/ (flat structure)
- Remove entire Versioned/ folder (26 samples)
- Add FoundryAgent_Step01 sample showing direct FoundryAgent ctor usage
- Update slnx to reflect flat folder structure
- Fix csproj ProjectReference paths for new depth

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update READMEs for flat AgentsWithFoundry structure

- Rewrite AgentsWithFoundry/README.md with FoundryAgent quick start
- Fix cd commands and paths in 11 sample READMEs
- Update 02-agents/README.md to single Foundry link
- Update AGENTS.md tree to flat structure
- Fix AgentWithMemory cross-reference

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix FoundryAgent_Step01 sample with full create/run/delete lifecycle

Show the complete server-side agent lifecycle: create version with
native SDK, wrap as FoundryAgent via AsAIAgent, run, then delete.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Revert RAPI samples to use AIAgent instead of FoundryAgent

RAPI samples should not reference FoundryAgent directly. Restored
original sample code with only ChatClientAgent -> AIAgent type change
to accommodate the AsAIAgent return type.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Convert versioned-pattern samples to pure RAPI

Step09, Step13, Step17, Step22 were using CreateAgentVersionAsync +
PromptAgentDefinition which is the versioned pattern. Converted to
use AsAIAgent(model, instructions, tools) which is the RAPI path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix format issues from Docker CI check

- FoundryAgent_Step01: CRLF -> LF
- Agent_Step09: missing final newline
- Agent_Step11_Middleware: add internal modifier, final newline
- Agent_Step02: remove redundant cast (IDE0004)
- Agent_Step08: simplify name (IDE0001)
- FoundryAgentTests: s_ prefix, Async suffix naming conventions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Switch Step09 MCP sample to Microsoft Learn HTTP endpoint

Replace npx stdio GitHub MCP server with the public Microsoft Learn
MCP endpoint (https://learn.microsoft.com/api/mcp) using HTTP transport.
No external tooling required to run.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix missing final newline in Step09 MCP sample

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR review: use DelegatingAIAgent, clean up Step01 sample

- FoundryAgent now inherits DelegatingAIAgent instead of AIAgent,
  removing manual delegation boilerplate (westey-m feedback)
- Simplified Agent_Step01_Basics to single agent creation path,
  moved composable IChatClient approach to README (westey-m feedback)
- Fixed FoundryAgentTests param name assertion

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update sample using Project specialized type instead

* Address PR review feedback: DefaultAzureCredential warnings, sample simplifications, format fixes

- Add DefaultAzureCredential production warning comments to ~25 samples
- Simplify Anthropic and OpenAI Step01 samples to single agent
- Convert Step11 Middleware regex patterns to [GeneratedRegex]
- Remove unnecessary cleanup comment from Step06
- Fix Step09 README MCP transport description
- Enhance FoundryAgent xmldoc with non-persistent agent comparison

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Split Step02, simplify RAG Step04, sharpen Step23 differentiation

- Split Step02 into 02.1 (simple multi-turn via sessions) and 02.2 (server-side conversations via CreateConversationSessionAsync)
- RAG Step04: replace HostedFileSearchTool + MEAI wrapping with native OpenAI FileSearchTool
- Step23: clarify DelegatingAIFunction wrapping pattern vs Step09 basic MCP

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix Hosted MCP sample: use ResponseTool.CreateMcpTool and move tool to PromptAgentDefinition

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix broken README link after Step02 split

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address Sergey round 3 feedback: branding, README nav, sample rename

- Replace 'Azure AI Foundry' with 'Microsoft Foundry' in ADR 0020
- Fix 3 READMEs: 'ChatClientAgents' → 'AgentsWithFoundry' sample directory
- Rename FoundryAgent_Step01 → Agent_Step00_FoundryAgentLifecycle for naming consistency

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
f45fc7d402 · 2026-03-30 12:09:02 +00:00
History
..

AG-UI Getting Started Samples

This directory contains samples that demonstrate how to build AG-UI (Agent UI Protocol) servers and clients using the Microsoft Agent Framework.

Prerequisites

  • .NET 9.0 or later
  • Azure OpenAI service endpoint and deployment configured
  • Azure CLI installed and authenticated (az login)
  • User has the Cognitive Services OpenAI Contributor role for the Azure OpenAI resource

Environment Variables

All samples require the following environment variables:

export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini"

For the client samples, you can optionally set:

export AGUI_SERVER_URL="http://localhost:8888"

Samples

Step01_GettingStarted

A basic AG-UI server and client that demonstrate the foundational concepts.

Server (Step01_GettingStarted/Server)

A basic AG-UI server that hosts an AI agent accessible via HTTP. Demonstrates:

  • Creating an ASP.NET Core web application
  • Setting up an AG-UI server endpoint with MapAGUI
  • Creating an AI agent from an Azure OpenAI chat client
  • Streaming responses via Server-Sent Events (SSE)

Run the server:

cd Step01_GettingStarted/Server
dotnet run --urls http://localhost:8888

Client (Step01_GettingStarted/Client)

An interactive console client that connects to an AG-UI server. Demonstrates:

  • Creating an AG-UI client with AGUIChatClient
  • Managing conversation threads
  • Streaming responses with RunStreamingAsync
  • Displaying colored console output for different content types
  • Supporting both interactive and automated modes

Prerequisites: The Step01_GettingStarted server (or any AG-UI server) must be running.

Run the client:

cd Step01_GettingStarted/Client
dotnet run

Type messages and press Enter to interact with the agent. Type :q or quit to exit.

Step02_BackendTools

An AG-UI server with function tools that execute on the backend.

Server (Step02_BackendTools/Server)

Demonstrates:

  • Creating function tools using AIFunctionFactory.Create
  • Using [Description] attributes for tool documentation
  • Defining explicit request/response types for type safety
  • Setting up JSON serialization contexts for source generation
  • Backend tool rendering (tools execute on the server)

Run the server:

cd Step02_BackendTools/Server
dotnet run --urls http://localhost:8888

Client (Step02_BackendTools/Client)

A client that works with the backend tools server. Try asking: "Find Italian restaurants in Seattle" or "Search for Mexican food in Portland".

Run the client:

cd Step02_BackendTools/Client
dotnet run

Step03_FrontendTools

Demonstrates frontend tool rendering (tools defined on client, executed on server).

Server (Step03_FrontendTools/Server)

A basic AG-UI server that accepts tool definitions from the client.

Run the server:

cd Step03_FrontendTools/Server
dotnet run --urls http://localhost:8888

Client (Step03_FrontendTools/Client)

A client that defines and sends tools to the server for execution.

Run the client:

cd Step03_FrontendTools/Client
dotnet run

Step04_HumanInLoop

Demonstrates human-in-the-loop approval workflows for sensitive operations. This sample includes both a server and client component.

Server (Step04_HumanInLoop/Server)

An AG-UI server that implements approval workflows. Demonstrates:

  • Wrapping tools with ApprovalRequiredAIFunction
  • Converting FunctionApprovalRequestContent to approval requests
  • Middleware pattern with ServerFunctionApprovalServerAgent
  • Complete function call capture and restoration

Run the server:

cd Step04_HumanInLoop/Server
dotnet run --urls http://localhost:8888

Client (Step04_HumanInLoop/Client)

An interactive client that handles approval requests from the server. Demonstrates:

  • Using ServerFunctionApprovalClientAgent middleware
  • Detecting FunctionApprovalRequestContent
  • Displaying approval details to users
  • Prompting for approval/rejection
  • Sending approval responses with FunctionApprovalResponseContent
  • Resuming conversation after approval

Run the client:

cd Step04_HumanInLoop/Client
dotnet run

Try asking the agent to perform sensitive operations like "Approve expense report EXP-12345".

Step05_StateManagement

An AG-UI server and client that demonstrate state management with predictive updates.

Server (Step05_StateManagement/Server)

Demonstrates:

  • Defining state schemas using C# records
  • Using SharedStateAgent middleware for state management
  • Streaming predictive state updates with AgentState content
  • Managing shared state between client and server
  • Using JSON serialization contexts for state types

Run the server:

cd Step05_StateManagement/Server
dotnet run

The server runs on port 8888 by default.

Client (Step05_StateManagement/Client)

A client that displays and updates shared state from the server. Try asking: "Create a recipe for chocolate chip cookies" or "Suggest a pasta dish".

Run the client:

cd Step05_StateManagement/Client
dotnet run

How AG-UI Works

Server-Side

  1. Client sends HTTP POST request with messages
  2. ASP.NET Core endpoint receives the request via MapAGUI
  3. Agent processes messages using Agent Framework
  4. Responses are streamed back as Server-Sent Events (SSE)

Client-Side

  1. AGUIAgent sends HTTP POST request to server
  2. Server responds with SSE stream
  3. Client parses events into AgentResponseUpdate objects
  4. Updates are displayed based on content type
  5. ConversationId maintains conversation context

Protocol Features

  • HTTP POST for requests
  • Server-Sent Events (SSE) for streaming responses
  • JSON for event serialization
  • Thread IDs (as ConversationId) for conversation context
  • Run IDs (as ResponseId) for tracking individual executions

Troubleshooting

Connection Refused

Ensure the server is running before starting the client:

# Terminal 1
cd AGUI_Step01_ServerBasic
dotnet run --urls http://localhost:8888

# Terminal 2 (after server starts)
cd AGUI_Step02_ClientBasic
dotnet run

Port Already in Use

If port 8888 is already in use, choose a different port:

# Server
dotnet run --urls http://localhost:8889

# Client (set environment variable)
export AGUI_SERVER_URL="http://localhost:8889"
dotnet run

Authentication Errors

Make sure you're authenticated with Azure:

az login

Verify you have the Cognitive Services OpenAI Contributor role on the Azure OpenAI resource.

Missing Environment Variables

If you see "AZURE_OPENAI_ENDPOINT is not set" errors, ensure environment variables are set in your current shell session before running the samples.

Streaming Not Working

Check that the client timeout is sufficient (default is 60 seconds). For long-running operations, you may need to increase the timeout in the client code.

Next Steps

After completing these samples, explore more AG-UI capabilities:

Currently Available in C#

The samples above demonstrate the AG-UI features currently available in C#:

  • Basic Server and Client: Setting up AG-UI communication
  • Backend Tool Rendering: Function tools that execute on the server
  • Streaming Responses: Real-time Server-Sent Events
  • State Management: State schemas with predictive updates
  • Human-in-the-Loop: Approval workflows for sensitive operations

Coming Soon to C#

The following advanced AG-UI features are available in the Python implementation and are planned for future C# releases:

  • Generative UI: Custom UI component generation
  • Advanced State Patterns: Complex state synchronization scenarios

For the most up-to-date AG-UI features, see the Python samples for working examples.