Skip to content

.NET: Update to OpenAI 2.9.1, Azure.AI.OpenAI 2.9.0-beta.1, Microsoft.Extensions.AI 10.4.0, and Azure.AI.Projects 2.0.0-beta.2#4613

Merged
rogerbarreto merged 19 commits intomainfrom
copilot/update-openai-and-microsoft-extensions-ai
Mar 20, 2026
Merged

.NET: Update to OpenAI 2.9.1, Azure.AI.OpenAI 2.9.0-beta.1, Microsoft.Extensions.AI 10.4.0, and Azure.AI.Projects 2.0.0-beta.2#4613
rogerbarreto merged 19 commits intomainfrom
copilot/update-openai-and-microsoft-extensions-ai

Conversation

Copy link
Contributor

Copilot AI commented Mar 11, 2026

Motivation and Context

OpenAI 2.9.1, Azure.AI.OpenAI 2.9.0-beta.1, Microsoft.Extensions.AI 10.4.0, and Azure.AI.Projects 2.0.0-beta.2 introduced breaking API changes requiring updates across the codebase.

Description

Package bumps

  • OpenAI 2.8.0 → 2.9.1
  • Azure.AI.OpenAI 2.8.0-beta.1 → 2.9.0-beta.1 (central + 6 standalone HostedAgents projects)
  • Azure.AI.Projects 2.0.0-beta.1 → 2.0.0-beta.2
  • Microsoft.Extensions.AI / Microsoft.Extensions.AI.Abstractions / Microsoft.Extensions.AI.OpenAI 10.3.0 → 10.4.0
  • Azure.Identity 1.17.1 → 1.19.0, Microsoft.Identity.Client.Extensions.Msal 4.78.0 → 4.83.1
  • Associated transitive runtime deps 10.0.3 → 10.0.4

OpenAI 2.9.1 / Azure.AI.OpenAI 2.9.0-beta.1: model moved from GetResponsesClient to AsIChatClient/AsAIAgent

// Before
openAIClient.GetResponsesClient("gpt-4o").AsAIAgent(instructions: "...");

// After
openAIClient.GetResponsesClient().AsAIAgent("gpt-4o", instructions: "...");

Updated OpenAIResponseClientExtensions, all samples (including Agent_With_AzureOpenAIResponses, Agent_Step14_BackgroundResponses, Agent_Step10_BackgroundResponsesWithToolsAndPersistence, Agent_Step01_BasicSkills, ResponseAgent_Hosted_MCP, AgentWithPurview), integration test fixtures, and OpenAIResponsesAgentClient. Each call site passes the model/deployment name via AsAIAgent(model: ...), AsIChatClient(model), or AsIChatClientWithStoredOutputDisabled(model: ...) instead of through GetResponsesClient.

For standalone HostedAgents samples referencing published Microsoft.Agents.AI.OpenAI 1.0.0-rc1 (which lacks the updated AsAIAgent with model parameter), the AgentWithHostedMCP sample uses .GetResponsesClient().AsIChatClient(model).AsAIAgent(...) with an explicit Microsoft.Extensions.AI.OpenAI 10.4.0 dependency to get the AsIChatClient(ResponsesClient, string) overload.

Azure.AI.Projects 2.0.0-beta.2: package restructuring and namespace migration

Azure.AI.Projects.OpenAI has been replaced by Azure.AI.Extensions.OpenAI and Azure.AI.Projects.Agents — both come transitively from Azure.AI.Projects 2.0.0-beta.2 (no explicit entries needed in Directory.Packages.props).

  • using Azure.AI.Projects.OpenAIusing Azure.AI.Extensions.OpenAI across all files
  • Agent types (AgentRecord, AgentVersion, AgentVersionCreationOptions, PromptAgentDefinition, AgentDefinition, AgentsClient, etc.) moved to Azure.AI.Projects.Agents namespace — added using Azure.AI.Projects.Agents where needed
  • AgentRecord.Versions.LatestAgentRecord.GetLatestVersion() (the Versions property is now internal)
  • AzureAIProjectsOpenAIContext / AzureAIProjectsContextAzureAIProjectsAgentsContext
  • AIProjectAgentsOperationsAgentsClient
  • Renamed types: OpenAPIFunctionDefinitionOpenApiFunctionDefinition, BingCustomSearchToolParametersBingCustomSearchToolOptions, BrowserAutomationToolParametersBrowserAutomationToolOptions
  • MemorySearchPreviewTool.UpdateDelay.UpdateDelayInSecs
  • WaitForMemoriesUpdateAsync parameter order changed: pollingInterval now comes before options
  • Removed explicit Azure.AI.Projects.OpenAI / Azure.AI.Extensions.OpenAI package references from csproj files (transitive from Azure.AI.Projects)

ME.AI 10.4.0: approval content type unification

FunctionApprovalRequestContent, FunctionApprovalResponseContent, UserInputRequestContent, UserInputResponseContent, and McpServerToolApprovalRequestContent/McpServerToolApprovalResponseContent are all replaced by ToolApprovalRequestContent / ToolApprovalResponseContent. Constructor param id:requestId:. Property .Id.RequestId.

Updated across ~30 files including sources, samples, and tests. Key behavioral changes:

  • WorkflowRunner: merged separate ApproveFunction + ApproveMCP handlers into a single ApproveToolCall dispatching on ToolCall type via switch expression
  • FunctionApprovalRequestEventGenerator: replaced hard cast (FunctionCallContent)approvalRequest.ToolCall with pattern match; silently skips non-function approval requests (e.g., MCP) rather than throwing
  • MCP samples: ToolApprovalRequestContent.ToolCall is now ToolCallContent (base); must cast to McpServerToolCallContent to access .Name (was .ToolName) and .ServerName
  • Client/Program.cs and ServerFunctionApprovalServerAgent.cs: replaced unsafe (FunctionCallContent)approvalRequest.ToolCall casts with safe when approvalRequest.ToolCall is FunctionCallContent fcc pattern matching, ensuring only function-based approvals are handled
  • TestRequestAgent.cs: removed redundant type checks in CreatePairedResponse and ProcessResponse where the parameter was already typed as ToolApprovalRequestContent/ToolApprovalResponseContent, and fixed incorrect exception messages that referenced wrong types
  • AIAgentHostExecutor.cs: updated error message from "No pending UserInputRequest found..." to "No pending ToolApprovalRequest found..." to correctly reflect the handler now processes ToolApprovalResponseContent

ME.AI 10.4.0: McpServerToolResultContent.Output.Outputs

Updated in InvokeMcpToolExecutor, DefaultMcpToolHandler, and test mocks.

Other

  • Added #pragma warning disable OPENAI001 for AsOpenAIStreamingChatCompletionUpdatesAsync, newly marked experimental in 2.9.1
  • CreateResponseAsync/CreateResponseStreamingAsync signatures updated in integration tests

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

@markwallace-microsoft markwallace-microsoft added .NET workflows Related to Workflows in agent-framework labels Mar 11, 2026
@github-actions github-actions bot changed the title Update to OpenAI 2.9.1 and Microsoft.Extensions.AI 10.4.0 .NET: Update to OpenAI 2.9.1 and Microsoft.Extensions.AI 10.4.0 Mar 11, 2026
@stephentoub stephentoub marked this pull request as ready for review March 11, 2026 02:45
Copilot AI review requested due to automatic review settings March 11, 2026 02:45
@stephentoub
Copy link
Member

This will be broken until Azure.AI.OpenAI and Azure.AI.Projects update to OpenAI 2.9.1.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the .NET Agent Framework codebase to align with newer OpenAI Responses client patterns (model passed per request / per chat client) and consolidates “approval required” flows under unified tool-approval content types across workflows, hosting, tests, and samples.

Changes:

  • Switch OpenAI Responses usage to GetResponsesClient() without a baked-in model, and plumb model IDs via AsIChatClient(model) / per-request parameters.
  • Replace function/MCP-specific approval content with ToolApprovalRequestContent / ToolApprovalResponseContent across workflows, hosting streaming events, tests, and samples.
  • Update MCP tool result handling from Output to Outputs, and bump several .NET package versions.

Reviewed changes

Copilot reviewed 39 out of 39 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
dotnet/tests/OpenAIResponse.IntegrationTests/OpenAIResponseFixture.cs Stores model name separately and passes it into AsIChatClient(model) after switching to model-less GetResponsesClient().
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/TestRequestAgent.cs Updates unit-test agent session/request plumbing to use tool-approval request/response content types.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/AIAgentHostExecutorTests.cs Adjusts request interception tests to expect ToolApprovalRequestContent.
dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/ObjectModel/InvokeMcpToolExecutorTest.cs Updates MCP approval tests to use tool-approval content + renames OutputOutputs in mocked results.
dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/Events/ExternalInputResponseTest.cs Updates serialization assertions for unified tool-approval response content.
dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/Events/ExternalInputRequestTest.cs Updates serialization assertions for unified tool-approval request content.
dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/InvokeToolWorkflowTest.cs Updates integration test handling/logging for unified tool approvals.
dotnet/tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/OpenAIResponsesIntegrationTests.cs Updates tests for new ResponsesClient usage and per-call model passing.
dotnet/tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/FunctionApprovalTests.cs Renames regions and swaps approval content types to tool-approval equivalents.
dotnet/src/Shared/Workflows/Execution/WorkflowRunner.cs Consolidates approval auto-response handling to a single tool-approval path.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/AIAgentHostExecutor.cs Switches “user input” interception path to tool-approval request/response content.
dotnet/src/Microsoft.Agents.AI.Workflows/AIAgentHostOptions.cs Updates XML docs to reference ToolApprovalRequestContent.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeMcpToolExecutor.cs Uses tool-approval request/response and migrates MCP result payload to Outputs.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeFunctionToolExecutor.cs Emits tool-approval requests for function tools that require approval.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeAzureAgentExecutor.cs Treats tool-approval requests as “blocking” content when filtering responses.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/DefaultMcpToolHandler.cs Renames MCP tool result list from Output to Outputs and updates population logic.
dotnet/src/Microsoft.Agents.AI.OpenAI/Extensions/OpenAIResponseClientExtensions.cs Adds optional model plumbing to agent/chat-client helpers for plain ResponsesClient usage.
dotnet/src/Microsoft.Agents.AI.OpenAI/ChatClient/AsyncStreamingChatCompletionUpdateCollectionResult.cs Suppresses OPENAI001 experimental warnings at file scope.
dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/Streaming/FunctionApprovalResponseEventGenerator.cs Renames generator to tool-approval response generator and maps RequestId.
dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/Streaming/FunctionApprovalRequestEventGenerator.cs Renames generator to tool-approval request generator and handles non-function tool calls by skipping.
dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/AgentResponseUpdateExtensions.cs Switches streaming event generator selection to tool-approval content types.
dotnet/samples/05-end-to-end/M365Agent/AFAgentApplication.cs Updates sample approval card plumbing to deserialize/handle tool-approval content.
dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.Web/OpenAIResponsesAgentClient.cs Uses model-less ResponsesClient and passes model via AsIChatClient(agentName).
dotnet/samples/03-workflows/Agents/GroupChatToolApproval/Program.cs Updates sample to read tool-approval requests and extract function call info via ToolCall.
dotnet/samples/02-agents/ModelContextProtocol/ResponseAgent_Hosted_MCP/Program.cs Updates MCP approval loop to use unified tool-approval request content.
dotnet/samples/02-agents/ModelContextProtocol/FoundryAgent_Hosted_MCP/Program.cs Updates MCP approval loop to use unified tool-approval request content.
dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step12_Middleware/Program.cs Updates middleware example to use tool-approval request content.
dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step04_UsingFunctionToolsWithApprovals/Program.cs Updates function-approval loop example to use tool-approval request content.
dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Server/ServerFunctionApprovalServerAgent.cs Updates server-side approval translation to tool-approval content types.
dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Client/ServerFunctionApprovalClientAgent.cs Updates client-side approval translation to tool-approval content types.
dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Client/Program.cs Updates console client to display/answer tool-approval requests.
dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step05_Conversation/Program.cs Updates agent creation to pass model via AsIChatClient(model) with model-less GetResponsesClient().
dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step04_CreateFromOpenAIResponseClient/Program.cs Updates sample agent instantiation to supply model separately.
dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step04_CreateFromOpenAIResponseClient/OpenAIResponseClientAgent.cs Adds optional model parameter and passes it into AsIChatClient(model).
dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step02_Reasoning/Program.cs Updates reasoning sample to pass model through AsIChatClient(model).
dotnet/samples/02-agents/Agents/Agent_Step11_Middleware/Program.cs Updates middleware example to use tool-approval request content.
dotnet/samples/02-agents/Agents/Agent_Step01_UsingFunctionToolsWithApprovals/Program.cs Updates function-approval loop example to use tool-approval request content.
dotnet/samples/02-agents/AgentProviders/Agent_With_OpenAIResponses/Program.cs Updates provider example to pass model via .AsAIAgent(model: ...) with model-less GetResponsesClient().
dotnet/Directory.Packages.props Bumps multiple package versions (System., Microsoft.Extensions.AI, OpenAI).
Comments suppressed due to low confidence (2)

dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/TestRequestAgent.cs:216

  • The Invalid request exception message in ProcessResponse is misleading: it reports it expects ToolApprovalResponseContent when it is actually validating the request pulled from UnservicedRequests. This makes debugging test failures harder; update the message (or remove the redundant type-check since request is already ToolApprovalRequestContent).
    dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Server/ServerFunctionApprovalServerAgent.cs:196
  • ToolApprovalRequestContent can wrap approvals for non-function tool calls (e.g., MCP). This code unconditionally casts request.ToolCall to FunctionCallContent, which will throw InvalidCastException or incorrectly transform non-function approvals. Please guard with if (request.ToolCall is FunctionCallContent functionCall) and skip/handle other tool-call types.
#pragma warning disable MEAI001 // Type is for evaluation purposes only
            if (content is ToolApprovalRequestContent request && request.ToolCall is FunctionCallContent functionCall)
            {
                updatedContents ??= [.. update.Contents];
                var approvalId = request.RequestId;

                var approvalData = new ApprovalRequest
                {
                    ApprovalId = approvalId,
                    FunctionName = functionCall.Name,
                    FunctionArguments = functionCall.Arguments,
                    Message = $"Approve execution of '{functionCall.Name}'?"
                };

@rogerbarreto rogerbarreto added the blocked external This label indicates whenever an issue or a PR cannot proceed due to an external dependency label Mar 11, 2026
@stephentoub
Copy link
Member

@copilot please also update Azure.AI.OpenAI to 2.9.0-beta.1

Copy link
Contributor Author

Copilot AI commented Mar 17, 2026

@copilot please also update Azure.AI.OpenAI to 2.9.0-beta.1

Done in 8464b45. Updated Azure.AI.OpenAI to 2.9.0-beta.1 in Directory.Packages.props and all 6 standalone HostedAgents projects. Also fixed AgentWithHostedMCP/Program.cs to use .GetResponsesClient().AsIChatClient(deploymentName) since GetResponsesClient() no longer takes a model parameter, and added Microsoft.Extensions.AI.OpenAI 10.4.0 as a direct dependency to get the AsIChatClient(ResponsesClient, string) overload.

Copilot AI changed the title .NET: Update to OpenAI 2.9.1 and Microsoft.Extensions.AI 10.4.0 .NET: Update to OpenAI 2.9.1, Azure.AI.OpenAI 2.9.0-beta.1, and Microsoft.Extensions.AI 10.4.0 Mar 17, 2026
Copilot AI requested a review from stephentoub March 17, 2026 01:50
Azure.AI.Agents.Persistent 1.2.0-beta.9 references McpServerToolApprovalResponseContent
which was removed in ME.AI 10.4.0 (renamed to ToolApprovalResponseContent), causing
TypeLoadException at runtime. Mark all 6 test classes with IntegrationDisabled trait
until Persistent ships a version targeting ME.AI 10.4.0+.

Upstream fix: Azure/azure-sdk-for-net#56929

Co-authored-by: Copilot <[email protected]>
Documents that Azure.AI.Agents.Persistent 1.2.0-beta.9 is only compatible
with ME.AI ≤10.3.0 and OpenAI ≤2.8.0 due to type renames in ME.AI 10.4.0.

Co-authored-by: Copilot <[email protected]>
@markwallace-microsoft markwallace-microsoft added the documentation Improvements or additions to documentation label Mar 18, 2026
@rogerbarreto rogerbarreto added this pull request to the merge queue Mar 19, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 19, 2026
Prevent shipping until Azure.AI.Agents.Persistent targets ME.AI 10.4.0+.

Co-authored-by: Copilot <[email protected]>
@rogerbarreto rogerbarreto enabled auto-merge March 19, 2026 15:56
@rogerbarreto rogerbarreto added this pull request to the merge queue Mar 20, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 20, 2026
@rogerbarreto rogerbarreto added this pull request to the merge queue Mar 20, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 20, 2026
@rogerbarreto rogerbarreto added this pull request to the merge queue Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blocked external This label indicates whenever an issue or a PR cannot proceed due to an external dependency documentation Improvements or additions to documentation .NET workflows Related to Workflows in agent-framework

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

9 participants