From b30af494ef5b3ad26efd4dd7892b360a813dc23d Mon Sep 17 00:00:00 2001
From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com>
Date: Tue, 1 Sep 2026 15:18:44 +0100
Subject: [PATCH 1/3] .NET: Update Azure AI Projects to 3.0.0 beta 1
Migrate Foundry consumers to the OpenAI 2.12 response and conversation types while preserving Azure.AI.OpenAI compatibility through scoped package overrides.
Refs #7994
Copilot-Session: 57730879-50c2-46e6-82f6-ddf01a29ba0c
---
dotnet/Directory.Packages.props | 6 +++---
.../Program.cs | 5 +++--
.../Agent_Step18_BingCustomSearch.csproj | 1 +
.../Agent_Step19_SharePoint.csproj | 1 +
.../Agent_Step20_MicrosoftFabric.csproj | 1 +
.../Agent_Step22_MemorySearch.csproj | 1 +
.../Agent_Step22_MemorySearch/Program.cs | 5 ++---
...emory_Step06_MemoryUsingAgentMemory.csproj | 2 +-
.../Declarative/HostedWorkflow/Program.cs | 4 ++--
.../Visualization/Visualization.csproj | 5 +++++
.../Hosted-Steering/HostedSteering.csproj | 3 ++-
.../HostedWorkflowResilient.csproj | 3 ++-
.../AgentWebChat.AgentHost.csproj | 3 ++-
.../OpenAIResponsesAgentClient.cs | 3 +--
.../HostedAgentUserAgentPolicy.cs | 2 +-
.../ServiceCollectionExtensions.cs | 2 +-
.../ClientHeadersExtensions.cs | 2 +-
.../ClientHeadersPolicy.cs | 4 ++--
.../Microsoft.Agents.AI.Foundry.csproj | 5 +++--
.../ServedModelPolicy.cs | 2 +-
.../Microsoft.Agents.AI.OpenAI.csproj | 4 +++-
.../AzureAgentProvider.cs | 11 +++++-----
.../Fixtures/HostedAgentFixture.cs | 4 ++--
.../Foundry.Hosting.IntegrationTests.csproj | 2 +-
.../Foundry.IntegrationTests.csproj | 2 +-
.../FoundryVersionedAgentFixture.cs | 6 ++----
.../ResponsesAgentExtensionCreateTests.cs | 3 ++-
.../ResponsesAgentFixture.cs | 6 ++----
.../FoundryAIToolExtensionsTests.cs | 2 +-
.../HostedOutboundUserAgentTests.cs | 4 ++--
.../AIProjectClientExtensionsTests.cs | 20 +++++++++----------
.../FoundryAgentTests.cs | 2 +-
.../MeaiAutoUserAgentVerificationTests.cs | 5 ++---
...crosoft.Agents.AI.Foundry.UnitTests.csproj | 2 +-
...HostingServiceCollectionExtensionsTests.cs | 3 +--
.../OpenAIResponsesIntegrationTests.cs | 3 +--
.../PolicyPipelineInvestigationTests.cs | 0
.../OpenTelemetryAgentTests.cs | 2 +-
38 files changed, 75 insertions(+), 66 deletions(-)
rename dotnet/tests/{Microsoft.Agents.AI.Foundry.UnitTests => Microsoft.Agents.AI.OpenAI.UnitTests}/PolicyPipelineInvestigationTests.cs (100%)
diff --git a/dotnet/Directory.Packages.props b/dotnet/Directory.Packages.props
index 3e94a182dd2..7d8852c2659 100644
--- a/dotnet/Directory.Packages.props
+++ b/dotnet/Directory.Packages.props
@@ -27,7 +27,7 @@
-
+
@@ -84,7 +84,7 @@
-
+
@@ -128,7 +128,7 @@
-
+
diff --git a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step02.2_MultiturnWithServerConversations/Program.cs b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step02.2_MultiturnWithServerConversations/Program.cs
index c41d9713f37..16bfe4d5602 100644
--- a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step02.2_MultiturnWithServerConversations/Program.cs
+++ b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step02.2_MultiturnWithServerConversations/Program.cs
@@ -8,6 +8,7 @@
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
+using OpenAI.Conversations;
string endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("FOUNDRY_MODEL") ?? "gpt-5.4-mini";
@@ -24,9 +25,9 @@
.GetProjectOpenAIClient()
.GetProjectConversationsClient();
-ProjectConversation conversation = (await conversationsClient.CreateProjectConversationAsync().ConfigureAwait(false)).Value;
+ConversationResource conversation = (await conversationsClient.CreateProjectConversationAsync().ConfigureAwait(false)).Value;
-// CreateConversationSessionAsync creates a server-side ProjectConversation
+// CreateConversationSessionAsync creates a server-side ConversationResource
// that persists on the Foundry service and is visible in the Foundry Project UI.
AgentSession session = await agent.CreateSessionAsync(conversation.Id);
diff --git a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step18_BingCustomSearch/Agent_Step18_BingCustomSearch.csproj b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step18_BingCustomSearch/Agent_Step18_BingCustomSearch.csproj
index b00975905a4..351be63a94d 100644
--- a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step18_BingCustomSearch/Agent_Step18_BingCustomSearch.csproj
+++ b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step18_BingCustomSearch/Agent_Step18_BingCustomSearch.csproj
@@ -6,6 +6,7 @@
enable
enable
+ $(NoWarn);AAIP001
diff --git a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step19_SharePoint/Agent_Step19_SharePoint.csproj b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step19_SharePoint/Agent_Step19_SharePoint.csproj
index b00975905a4..351be63a94d 100644
--- a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step19_SharePoint/Agent_Step19_SharePoint.csproj
+++ b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step19_SharePoint/Agent_Step19_SharePoint.csproj
@@ -6,6 +6,7 @@
enable
enable
+ $(NoWarn);AAIP001
diff --git a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step20_MicrosoftFabric/Agent_Step20_MicrosoftFabric.csproj b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step20_MicrosoftFabric/Agent_Step20_MicrosoftFabric.csproj
index b00975905a4..351be63a94d 100644
--- a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step20_MicrosoftFabric/Agent_Step20_MicrosoftFabric.csproj
+++ b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step20_MicrosoftFabric/Agent_Step20_MicrosoftFabric.csproj
@@ -6,6 +6,7 @@
enable
enable
+ $(NoWarn);AAIP001
diff --git a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step22_MemorySearch/Agent_Step22_MemorySearch.csproj b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step22_MemorySearch/Agent_Step22_MemorySearch.csproj
index feb74168cd2..b1ad80d32d9 100644
--- a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step22_MemorySearch/Agent_Step22_MemorySearch.csproj
+++ b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step22_MemorySearch/Agent_Step22_MemorySearch.csproj
@@ -6,6 +6,7 @@
enable
enable
+ $(NoWarn);AAIP001
diff --git a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step22_MemorySearch/Program.cs b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step22_MemorySearch/Program.cs
index 08531f6edd0..8db823e49c3 100644
--- a/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step22_MemorySearch/Program.cs
+++ b/dotnet/samples/02-agents/AgentProviders/foundry/Agent_Step22_MemorySearch/Program.cs
@@ -6,7 +6,6 @@
using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects;
-using Azure.AI.Projects.Agents;
using Azure.AI.Projects.Memory;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -29,7 +28,7 @@ Use the memory search tool to recall relevant information from previous interact
string userScope = $"user_{Environment.MachineName}";
-MemorySearchPreviewTool memorySearchTool = new(memoryStoreName, userScope) { UpdateDelayInSecs = 0 };
+MemorySearchPreviewTool memorySearchTool = new(memoryStoreName, userScope) { UpdateDelayInSeconds = 0 };
// WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production.
// In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid
// latency issues, unintended credential probing, and potential security risks from fallback mechanisms.
@@ -66,7 +65,7 @@ Use the memory search tool to recall relevant information from previous interact
Console.WriteLine($" - Memory ID: {memoryItem.MemoryId}");
Console.WriteLine($" Scope: {memoryItem.Scope}");
Console.WriteLine($" Content: {memoryItem.Content}");
- Console.WriteLine($" Updated: {memoryItem.UpdatedAt}");
+ Console.WriteLine($" Updated: {memoryItem.UpdatedOn}");
}
}
}
diff --git a/dotnet/samples/02-agents/AgentWithMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory.csproj b/dotnet/samples/02-agents/AgentWithMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory.csproj
index 446f7f8bbe3..4224265ea15 100644
--- a/dotnet/samples/02-agents/AgentWithMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory.csproj
+++ b/dotnet/samples/02-agents/AgentWithMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory.csproj
@@ -42,7 +42,7 @@
-
+
+ ships a stable 3.0.0. -->
true
true
+ $(NoWarn);AAIP001;OPENAI001;SCME0001
diff --git a/dotnet/src/Microsoft.Agents.AI.Foundry/ServedModelPolicy.cs b/dotnet/src/Microsoft.Agents.AI.Foundry/ServedModelPolicy.cs
index 27e98b7b7df..5339a2bdabe 100644
--- a/dotnet/src/Microsoft.Agents.AI.Foundry/ServedModelPolicy.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Foundry/ServedModelPolicy.cs
@@ -18,7 +18,7 @@ namespace Microsoft.Agents.AI.Foundry;
/// can overwrite ChatResponse.ModelId with the true model name.
///
///
-/// Registered once per OpenAIRequestPolicies instance via the MEAI 10.5.1 extension hook.
+/// Registered once per OpenAIRequestPolicies instance via the MEAI 10.9.0 extension hook.
/// When the header is absent (non-Azure endpoints), the scope is not set and the
/// preserves the original model name.
///
diff --git a/dotnet/src/Microsoft.Agents.AI.OpenAI/Microsoft.Agents.AI.OpenAI.csproj b/dotnet/src/Microsoft.Agents.AI.OpenAI/Microsoft.Agents.AI.OpenAI.csproj
index e9a664f5758..1f4646475b2 100644
--- a/dotnet/src/Microsoft.Agents.AI.OpenAI/Microsoft.Agents.AI.OpenAI.csproj
+++ b/dotnet/src/Microsoft.Agents.AI.OpenAI/Microsoft.Agents.AI.OpenAI.csproj
@@ -15,7 +15,9 @@
-
+
+
+
diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Foundry/AzureAgentProvider.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Foundry/AzureAgentProvider.cs
index ac5e7056ecc..a89f9b91550 100644
--- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Foundry/AzureAgentProvider.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Foundry/AzureAgentProvider.cs
@@ -15,6 +15,7 @@
using Azure.AI.Projects.Agents;
using Azure.Core;
using Microsoft.Extensions.AI;
+using OpenAI.Conversations;
using OpenAI.Responses;
namespace Microsoft.Agents.AI.Workflows.Declarative;
@@ -53,7 +54,7 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
///
public override async Task CreateConversationAsync(CancellationToken cancellationToken = default)
{
- ProjectConversation conversation =
+ ConversationResource conversation =
await this.GetConversationClient()
.CreateProjectConversationAsync(options: null, cancellationToken).ConfigureAwait(false);
@@ -280,8 +281,8 @@ private async Task GetAgentAsync(ProjectsAgentVersion agentVersion, Can
///
public override async Task GetMessageAsync(string conversationId, string messageId, CancellationToken cancellationToken = default)
{
- AgentResponseItem responseItem = await this.GetConversationClient().GetProjectConversationItemAsync(conversationId, messageId, include: null, cancellationToken).ConfigureAwait(false);
- ResponseItem[] items = [responseItem.AsResponseResultItem()];
+ ResponseItem responseItem = await this.GetConversationClient().GetProjectConversationItemAsync(conversationId, messageId, include: null, cancellationToken).ConfigureAwait(false);
+ ResponseItem[] items = [responseItem];
ChatMessage[] messages = [.. items.AsChatMessages()];
if (messages.Length != 1)
{
@@ -303,9 +304,9 @@ public override async IAsyncEnumerable GetMessagesAsync(
{
AgentListOrder order = newestFirst ? AgentListOrder.Ascending : AgentListOrder.Descending;
- await foreach (AgentResponseItem responseItem in this.GetConversationClient().GetProjectConversationItemsAsync(conversationId, null, limit, order.ToString(), after, before, include: null, cancellationToken).ConfigureAwait(false))
+ await foreach (ResponseItem responseItem in this.GetConversationClient().GetProjectConversationItemsAsync(conversationId, null, limit, order.ToString(), after, before, include: null, cancellationToken).ConfigureAwait(false))
{
- ResponseItem[] items = [responseItem.AsResponseResultItem()];
+ ResponseItem[] items = [responseItem];
foreach (ChatMessage message in items.AsChatMessages())
{
yield return message;
diff --git a/dotnet/tests/Foundry.Hosting.IntegrationTests/Fixtures/HostedAgentFixture.cs b/dotnet/tests/Foundry.Hosting.IntegrationTests/Fixtures/HostedAgentFixture.cs
index c44f642830f..f5dfaa96a63 100644
--- a/dotnet/tests/Foundry.Hosting.IntegrationTests/Fixtures/HostedAgentFixture.cs
+++ b/dotnet/tests/Foundry.Hosting.IntegrationTests/Fixtures/HostedAgentFixture.cs
@@ -157,9 +157,9 @@ public async Task CountConversationItemsAsync(string conversationId)
public async Task> ReadConversationMessagesAsync(string conversationId)
{
List<(string Role, string Text)> messages = [];
- await foreach (AgentResponseItem item in this.AgentOpenAIClient.GetProjectConversationsClient().GetProjectConversationItemsAsync(conversationId, order: "asc").ConfigureAwait(false))
+ await foreach (ResponseItem item in this.AgentOpenAIClient.GetProjectConversationsClient().GetProjectConversationItemsAsync(conversationId, order: "asc").ConfigureAwait(false))
{
- if (item.AsResponseResultItem() is MessageResponseItem message)
+ if (item is MessageResponseItem message)
{
var text = string.Concat(message.Content
.Where(c => c.Kind is ResponseContentPartKind.OutputText or ResponseContentPartKind.InputText)
diff --git a/dotnet/tests/Foundry.Hosting.IntegrationTests/Foundry.Hosting.IntegrationTests.csproj b/dotnet/tests/Foundry.Hosting.IntegrationTests/Foundry.Hosting.IntegrationTests.csproj
index 6f1236e7b47..c05108bf506 100644
--- a/dotnet/tests/Foundry.Hosting.IntegrationTests/Foundry.Hosting.IntegrationTests.csproj
+++ b/dotnet/tests/Foundry.Hosting.IntegrationTests/Foundry.Hosting.IntegrationTests.csproj
@@ -7,7 +7,7 @@
inherits the default tests TFM list (net10.0;net472). The intersection is net10.0.
-->
net10.0
- $(NoWarn);CS8793;NU1605;NU1903;AAIP001
+ $(NoWarn);CS8793;NU1605;NU1903;AAIP001;SCME0001
false
True
True
diff --git a/dotnet/tests/Foundry.IntegrationTests/Foundry.IntegrationTests.csproj b/dotnet/tests/Foundry.IntegrationTests/Foundry.IntegrationTests.csproj
index dbff50104c9..5ff0a38a6db 100644
--- a/dotnet/tests/Foundry.IntegrationTests/Foundry.IntegrationTests.csproj
+++ b/dotnet/tests/Foundry.IntegrationTests/Foundry.IntegrationTests.csproj
@@ -1,7 +1,7 @@
- $(NoWarn);CS8793
+ $(NoWarn);AAIP001;CS8793
True
True
diff --git a/dotnet/tests/Foundry.IntegrationTests/FoundryVersionedAgentFixture.cs b/dotnet/tests/Foundry.IntegrationTests/FoundryVersionedAgentFixture.cs
index cceacfa40b5..f8d4d54be8a 100644
--- a/dotnet/tests/Foundry.IntegrationTests/FoundryVersionedAgentFixture.cs
+++ b/dotnet/tests/Foundry.IntegrationTests/FoundryVersionedAgentFixture.cs
@@ -6,7 +6,6 @@
using System.Threading.Tasks;
using AgentConformance.IntegrationTests;
using AgentConformance.IntegrationTests.Support;
-using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects;
using Azure.AI.Projects.Agents;
using Microsoft.Agents.AI;
@@ -97,10 +96,9 @@ private static ChatMessage ConvertToChatMessage(ResponseItem item)
private async Task> GetChatHistoryFromConversationAsync(string conversationId)
{
List messages = [];
- await foreach (AgentResponseItem item in this._client.GetProjectOpenAIClient().GetProjectConversationsClient().GetProjectConversationItemsAsync(conversationId, order: "asc"))
+ await foreach (ResponseItem item in this._client.GetProjectOpenAIClient().GetProjectConversationsClient().GetProjectConversationItemsAsync(conversationId, order: "asc"))
{
- var openAIItem = item.AsResponseResultItem();
- if (openAIItem is MessageResponseItem messageItem)
+ if (item is MessageResponseItem messageItem)
{
messages.Add(new ChatMessage
{
diff --git a/dotnet/tests/Foundry.IntegrationTests/ResponsesAgentExtensionCreateTests.cs b/dotnet/tests/Foundry.IntegrationTests/ResponsesAgentExtensionCreateTests.cs
index af358a9e556..c65bc44bcd2 100644
--- a/dotnet/tests/Foundry.IntegrationTests/ResponsesAgentExtensionCreateTests.cs
+++ b/dotnet/tests/Foundry.IntegrationTests/ResponsesAgentExtensionCreateTests.cs
@@ -7,6 +7,7 @@
using Azure.AI.Projects;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
+using OpenAI.Conversations;
using Shared.IntegrationTests;
namespace Foundry.IntegrationTests;
@@ -130,7 +131,7 @@ private static async Task DeleteResponseChainAsync(AIProjectClient client, strin
}
}
- private static async Task CreateConversationAsync(AIProjectClient client)
+ private static async Task CreateConversationAsync(AIProjectClient client)
{
ProjectConversationsClient conversationsClient = client.GetProjectOpenAIClient().GetProjectConversationsClient();
return (await conversationsClient.CreateProjectConversationAsync()).Value!;
diff --git a/dotnet/tests/Foundry.IntegrationTests/ResponsesAgentFixture.cs b/dotnet/tests/Foundry.IntegrationTests/ResponsesAgentFixture.cs
index 7bd0da0d953..57af7b34c48 100644
--- a/dotnet/tests/Foundry.IntegrationTests/ResponsesAgentFixture.cs
+++ b/dotnet/tests/Foundry.IntegrationTests/ResponsesAgentFixture.cs
@@ -6,7 +6,6 @@
using System.Threading.Tasks;
using AgentConformance.IntegrationTests;
using AgentConformance.IntegrationTests.Support;
-using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -88,10 +87,9 @@ private static ChatMessage ConvertToChatMessage(ResponseItem item)
private async Task> GetChatHistoryFromConversationAsync(string conversationId)
{
List messages = [];
- await foreach (AgentResponseItem item in this._client.GetProjectOpenAIClient().GetProjectConversationsClient().GetProjectConversationItemsAsync(conversationId, order: "asc"))
+ await foreach (ResponseItem item in this._client.GetProjectOpenAIClient().GetProjectConversationsClient().GetProjectConversationItemsAsync(conversationId, order: "asc"))
{
- var openAIItem = item.AsResponseResultItem();
- if (openAIItem is MessageResponseItem messageItem)
+ if (item is MessageResponseItem messageItem)
{
messages.Add(new ChatMessage
{
diff --git a/dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/FoundryAIToolExtensionsTests.cs b/dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/FoundryAIToolExtensionsTests.cs
index 022fbf0bfe1..5cd3cb85fd1 100644
--- a/dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/FoundryAIToolExtensionsTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/FoundryAIToolExtensionsTests.cs
@@ -54,7 +54,7 @@ public void CreateHostedMcpToolbox_FromToolboxVersion_UsesNameAndVersion()
name: "hr-tools",
version: "2025-09-01",
description: "HR toolbox",
- createdAt: DateTimeOffset.UtcNow,
+ createdOn: DateTimeOffset.UtcNow,
tools: null,
policies: null);
diff --git a/dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/HostedOutboundUserAgentTests.cs b/dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/HostedOutboundUserAgentTests.cs
index 6e9838ab120..1bd9f7e6152 100644
--- a/dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/HostedOutboundUserAgentTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/HostedOutboundUserAgentTests.cs
@@ -322,7 +322,7 @@ public async Task HostedAgentUserAgentPolicy_ReplacesDifferentVersionCombinedSeg
var pipeline = ClientPipeline.Create(
new ClientPipelineOptions { Transport = new HttpClientPipelineTransport(httpClient) },
- perCallPolicies: [new SetUserAgentPolicy("foundry-hosting/agent-framework-dotnet/0.0.1 MEAI/10.5.1"), HostedAgentUserAgentPolicy.Instance],
+ perCallPolicies: [new SetUserAgentPolicy("foundry-hosting/agent-framework-dotnet/0.0.1 MEAI/10.9.0"), HostedAgentUserAgentPolicy.Instance],
perTryPolicies: default,
beforeTransportPolicies: default);
@@ -342,7 +342,7 @@ public async Task HostedAgentUserAgentPolicy_ReplacesDifferentVersionCombinedSeg
Assert.True(firstCombined >= 0);
var secondCombined = handler.LastUserAgent.IndexOf("foundry-hosting/agent-framework-dotnet/", firstCombined + 1, StringComparison.Ordinal);
Assert.Equal(-1, secondCombined);
- Assert.Contains(" MEAI/10.5.1", handler.LastUserAgent, StringComparison.Ordinal);
+ Assert.Contains(" MEAI/10.9.0", handler.LastUserAgent, StringComparison.Ordinal);
// And the version that survives must be the runtime supplement value's version, not 0.0.1.
Assert.DoesNotContain("foundry-hosting/agent-framework-dotnet/0.0.1", handler.LastUserAgent, StringComparison.Ordinal);
diff --git a/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/AIProjectClientExtensionsTests.cs b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/AIProjectClientExtensionsTests.cs
index f4da9e6b772..ef500251343 100644
--- a/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/AIProjectClientExtensionsTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/AIProjectClientExtensionsTests.cs
@@ -674,25 +674,25 @@ public async Task CreateAIAgentAsync_WithResponseToolsInDefinition_CreatesAgentS
// Arrange
var definition = new DeclarativeAgentDefinition("test-model") { Instructions = "Test instructions" };
- var fabricToolOptions = new FabricDataAgentToolOptions();
- fabricToolOptions.ProjectConnections.Add(new ToolProjectConnection("connection-id"));
+ var fabricToolOptions = new Azure.AI.Projects.Agents.FabricDataAgentToolOptions();
+ fabricToolOptions.ProjectConnections.Add(new Azure.AI.Projects.Agents.ToolProjectConnection("connection-id"));
- var sharepointOptions = new SharePointGroundingToolOptions();
- sharepointOptions.ProjectConnections.Add(new ToolProjectConnection("connection-id"));
+ var sharepointOptions = new Azure.AI.Projects.Agents.SharePointGroundingToolOptions();
+ sharepointOptions.ProjectConnections.Add(new Azure.AI.Projects.Agents.ToolProjectConnection("connection-id"));
- var structuredOutputs = new StructuredOutputDefinition("name", "description", new Dictionary { ["schema"] = BinaryData.FromString(AIJsonUtilities.CreateJsonSchema(new { id = "test" }.GetType()).ToString()) }, false);
+ var structuredOutputs = new Azure.AI.Projects.Agents.StructuredOutputDefinition("name", "description", new Dictionary { ["schema"] = BinaryData.FromString(AIJsonUtilities.CreateJsonSchema(new { id = "test" }.GetType()).ToString()) }, false);
// Add tools to the definition
definition.Tools.Add(ResponseTool.CreateFunctionTool("create_tool", BinaryData.FromString("{}"), strictModeEnabled: false));
- definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateBingCustomSearchTool(new BingCustomSearchToolOptions([new BingCustomSearchConfiguration("connection-id", "instance-name")])));
- definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateBrowserAutomationTool(new BrowserAutomationToolOptions(new BrowserAutomationToolConnectionParameters("id"))));
+ definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateBingCustomSearchTool(new Azure.AI.Projects.Agents.BingCustomSearchToolOptions([new BingCustomSearchConfiguration("connection-id", "instance-name")])));
+ definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateBrowserAutomationTool(new Azure.AI.Projects.Agents.BrowserAutomationToolOptions(new BrowserAutomationToolConnectionParameters("id"))));
definition.Tools.Add(ProjectsAgentTool.CreateA2ATool(new Uri("https://test-uri.microsoft.com")));
- definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateBingGroundingTool(new BingGroundingSearchToolOptions([new BingGroundingSearchConfiguration("connection-id")])));
+ definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateBingGroundingTool(new Azure.AI.Projects.Agents.BingGroundingSearchToolOptions([new BingGroundingSearchConfiguration("connection-id")])));
definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateMicrosoftFabricTool(fabricToolOptions));
- definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateOpenApiTool(new OpenApiFunctionDefinition("name", BinaryData.FromString(OpenAPISpec), new OpenAPIAnonymousAuthenticationDetails())));
+ definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateOpenApiTool(new Azure.AI.Projects.Agents.OpenApiFunctionDefinition("name", BinaryData.FromString(OpenAPISpec), new OpenAPIAnonymousAuthenticationDetails())));
definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateSharepointTool(sharepointOptions));
definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateStructuredOutputsTool(structuredOutputs));
- definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateAzureAISearchTool(new AzureAISearchToolOptions([new AzureAISearchToolIndex() { IndexName = "name" }])));
+ definition.Tools.Add((ResponseTool)ProjectsAgentTool.CreateAzureAISearchTool(new Azure.AI.Projects.Agents.AzureAISearchToolOptions([new Azure.AI.Projects.Agents.AzureAISearchToolIndex() { IndexName = "name" }])));
// Generate agent definition response with the tools
var definitionResponse = GeneratePromptDefinitionResponse(definition, definition.Tools.Select(t => t.AsAITool()).ToList());
diff --git a/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/FoundryAgentTests.cs b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/FoundryAgentTests.cs
index 72e9fa342c0..0d9a22cbac7 100644
--- a/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/FoundryAgentTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/FoundryAgentTests.cs
@@ -406,7 +406,7 @@ public async Task Constructor_AgentFrameworkUserAgentHeaderAddedToRequestsAsync(
// FoundryAgent-built chat client carries the new agent-framework-dotnet/{version}
// segment (stamped by AgentFrameworkUserAgentPolicy registered via the MEAI
// OpenAIRequestPolicies hook). The local MEAI/{version} stamp was removed because
- // MEAI 10.5.1 stamps that itself; this test only verifies the framework-wide segment
+ // MEAI 10.9.0 stamps that itself; this test only verifies the framework-wide segment
// that the Foundry package now guarantees.
bool agentFrameworkUserAgentFound = false;
using HttpHandlerAssert httpHandler = new(request =>
diff --git a/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/MeaiAutoUserAgentVerificationTests.cs b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/MeaiAutoUserAgentVerificationTests.cs
index 050dd43a223..f99b81dd51d 100644
--- a/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/MeaiAutoUserAgentVerificationTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/MeaiAutoUserAgentVerificationTests.cs
@@ -9,7 +9,6 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.AI;
-using OpenAI;
using OpenAI.Responses;
#pragma warning disable OPENAI001
@@ -17,7 +16,7 @@
namespace Microsoft.Agents.AI.Foundry.UnitTests;
///
-/// One-shot verification (kept in tree to detect regressions) that MEAI 10.5.1 stamps its own
+/// One-shot verification (kept in tree to detect regressions) that MEAI 10.9.0 stamps its own
/// MEAI/{version} User-Agent segment automatically when an
/// is wrapped via AsIChatClient(). If this test starts failing, the FoundryChatClient
/// implementation must re-register the MEAI policy explicitly via OpenAIRequestPolicies because
@@ -36,7 +35,7 @@ public async Task MeaiOpenAIResponsesClient_StampsMeaiSegmentAutomatically_Witho
using var httpClient = new HttpClient(handler);
#pragma warning restore CA5399
- var options = new OpenAIClientOptions
+ var options = new ResponsesClientOptions
{
Transport = new HttpClientPipelineTransport(httpClient),
Endpoint = new Uri("https://example.test/v1"),
diff --git a/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Microsoft.Agents.AI.Foundry.UnitTests.csproj b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Microsoft.Agents.AI.Foundry.UnitTests.csproj
index 05b94b7b82f..89879a5a0c6 100644
--- a/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Microsoft.Agents.AI.Foundry.UnitTests.csproj
+++ b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Microsoft.Agents.AI.Foundry.UnitTests.csproj
@@ -2,7 +2,7 @@
false
- $(NoWarn);NU1605;NU1903
+ $(NoWarn);AAIP001;NU1605;NU1903
diff --git a/dotnet/tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/AgentHostingServiceCollectionExtensionsTests.cs b/dotnet/tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/AgentHostingServiceCollectionExtensionsTests.cs
index 587af5ff339..67471218e7e 100644
--- a/dotnet/tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/AgentHostingServiceCollectionExtensionsTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/AgentHostingServiceCollectionExtensionsTests.cs
@@ -11,7 +11,6 @@
using System.Threading.Tasks;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
-using OpenAI;
using OpenAI.Responses;
namespace Microsoft.Agents.AI.Hosting.OpenAI.UnitTests;
@@ -28,7 +27,7 @@ public async Task HostedWebSearchTool_WithResponsesClient_UsesResponsesWireForma
#pragma warning restore CA5399
using IChatClient chatClient = new ResponsesClient(
new ApiKeyCredential("test-key"),
- new OpenAIClientOptions
+ new ResponsesClientOptions
{
Endpoint = new Uri("https://example.test/v1"),
Transport = new HttpClientPipelineTransport(httpClient)
diff --git a/dotnet/tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/OpenAIResponsesIntegrationTests.cs b/dotnet/tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/OpenAIResponsesIntegrationTests.cs
index 9a89bee4838..4612ec35844 100644
--- a/dotnet/tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/OpenAIResponsesIntegrationTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/OpenAIResponsesIntegrationTests.cs
@@ -15,7 +15,6 @@
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-using OpenAI;
using OpenAI.Responses;
namespace Microsoft.Agents.AI.Hosting.OpenAI.UnitTests;
@@ -1321,7 +1320,7 @@ private ResponsesClient CreateResponseClient(string agentName)
{
return new ResponsesClient(
credential: new ApiKeyCredential("test-api-key"),
- options: new OpenAIClientOptions
+ options: new ResponsesClientOptions
{
Endpoint = new Uri(this._httpClient!.BaseAddress!, $"/{agentName}/v1/"),
Transport = new HttpClientPipelineTransport(this._httpClient)
diff --git a/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/PolicyPipelineInvestigationTests.cs b/dotnet/tests/Microsoft.Agents.AI.OpenAI.UnitTests/PolicyPipelineInvestigationTests.cs
similarity index 100%
rename from dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/PolicyPipelineInvestigationTests.cs
rename to dotnet/tests/Microsoft.Agents.AI.OpenAI.UnitTests/PolicyPipelineInvestigationTests.cs
diff --git a/dotnet/tests/Microsoft.Agents.AI.UnitTests/OpenTelemetryAgentTests.cs b/dotnet/tests/Microsoft.Agents.AI.UnitTests/OpenTelemetryAgentTests.cs
index 79e3418b862..a6b609e971e 100644
--- a/dotnet/tests/Microsoft.Agents.AI.UnitTests/OpenTelemetryAgentTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.UnitTests/OpenTelemetryAgentTests.cs
@@ -606,7 +606,7 @@ async static IAsyncEnumerable CallbackAsync(
Assert.False(tags.ContainsKey("gen_ai.system_instructions"));
// gen_ai.tool.definitions is always emitted regardless of EnableSensitiveData (ME.AI 10.4.0+).
- // ME.AI 10.5.1 omits description/parameters for function tools when sensitive data is disabled.
+ // ME.AI 10.9.0 omits description/parameters for function tools when sensitive data is disabled.
Assert.Equal(ReplaceWhitespace("""
[
{
From af61a79b16a674366f0666c9d9c2e4f40d878d3b Mon Sep 17 00:00:00 2001
From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com>
Date: Wed, 2 Sep 2026 16:08:44 +0100
Subject: [PATCH 2/3] .NET: Align SDK upgrade with current main
Remove obsolete compatibility overrides after Azure.AI.OpenAI removal and keep all projects on the OpenAI 2.12 dependency line.
Refs #7994
Copilot-Session: 57730879-50c2-46e6-82f6-ddf01a29ba0c
---
.../samples/03-workflows/Visualization/Visualization.csproj | 5 -----
.../Hosted-Workflow-Handoff/HostedWorkflowHandoff.csproj | 4 ++--
.../AgentWebChat.AgentHost/AgentWebChat.AgentHost.csproj | 3 +--
.../Microsoft.Agents.AI.OpenAI.csproj | 4 +---
.../PolicyPipelineInvestigationTests.cs | 2 +-
5 files changed, 5 insertions(+), 13 deletions(-)
rename dotnet/tests/{Microsoft.Agents.AI.OpenAI.UnitTests => Microsoft.Agents.AI.Foundry.UnitTests}/PolicyPipelineInvestigationTests.cs (99%)
diff --git a/dotnet/samples/03-workflows/Visualization/Visualization.csproj b/dotnet/samples/03-workflows/Visualization/Visualization.csproj
index ed1d92eba46..7f9f03dff47 100644
--- a/dotnet/samples/03-workflows/Visualization/Visualization.csproj
+++ b/dotnet/samples/03-workflows/Visualization/Visualization.csproj
@@ -8,11 +8,6 @@
enable
-
-
-
-
-
diff --git a/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Workflow-Handoff/HostedWorkflowHandoff.csproj b/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Workflow-Handoff/HostedWorkflowHandoff.csproj
index 9bdcf4161b6..43d63de1389 100644
--- a/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Workflow-Handoff/HostedWorkflowHandoff.csproj
+++ b/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Workflow-Handoff/HostedWorkflowHandoff.csproj
@@ -25,9 +25,9 @@
-
+
-
+
diff --git a/dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.AgentHost/AgentWebChat.AgentHost.csproj b/dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.AgentHost/AgentWebChat.AgentHost.csproj
index 78e6c97c874..e99de857c4c 100644
--- a/dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.AgentHost/AgentWebChat.AgentHost.csproj
+++ b/dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.AgentHost/AgentWebChat.AgentHost.csproj
@@ -26,8 +26,7 @@
-
-
+
diff --git a/dotnet/src/Microsoft.Agents.AI.OpenAI/Microsoft.Agents.AI.OpenAI.csproj b/dotnet/src/Microsoft.Agents.AI.OpenAI/Microsoft.Agents.AI.OpenAI.csproj
index 1f4646475b2..e9a664f5758 100644
--- a/dotnet/src/Microsoft.Agents.AI.OpenAI/Microsoft.Agents.AI.OpenAI.csproj
+++ b/dotnet/src/Microsoft.Agents.AI.OpenAI/Microsoft.Agents.AI.OpenAI.csproj
@@ -15,9 +15,7 @@
-
-
-
+
diff --git a/dotnet/tests/Microsoft.Agents.AI.OpenAI.UnitTests/PolicyPipelineInvestigationTests.cs b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/PolicyPipelineInvestigationTests.cs
similarity index 99%
rename from dotnet/tests/Microsoft.Agents.AI.OpenAI.UnitTests/PolicyPipelineInvestigationTests.cs
rename to dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/PolicyPipelineInvestigationTests.cs
index 3c4fdd45cb2..1d6b21291bf 100644
--- a/dotnet/tests/Microsoft.Agents.AI.OpenAI.UnitTests/PolicyPipelineInvestigationTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/PolicyPipelineInvestigationTests.cs
@@ -20,7 +20,7 @@
namespace Microsoft.Agents.AI.Foundry.UnitTests;
///
-/// Executable probes documenting the System.ClientModel policy behavior Stage 1 can rely on.
+/// Executable probes documenting the System.ClientModel policy behavior used by Foundry clients.
///
public sealed class PolicyPipelineInvestigationTests
{
From da1ca14405eb6c4aa898a3ede200874cb8f1024b Mon Sep 17 00:00:00 2001
From: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com>
Date: Wed, 2 Sep 2026 19:20:46 +0100
Subject: [PATCH 3/3] .NET: Use Projects 3 in hosted samples
Use the public Azure.AI.Projects 3.0.0 beta 1 package in both local and source deployment modes.
Refs #7994
Copilot-Session: 57730879-50c2-46e6-82f6-ddf01a29ba0c
---
.../responses/Hosted-Steering/HostedSteering.csproj | 3 +--
.../Hosted-Workflow-Resilient/HostedWorkflowResilient.csproj | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Steering/HostedSteering.csproj b/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Steering/HostedSteering.csproj
index 0e80e2ccdb3..8a2adf0facc 100644
--- a/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Steering/HostedSteering.csproj
+++ b/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Steering/HostedSteering.csproj
@@ -30,8 +30,7 @@
-
-
+
diff --git a/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Workflow-Resilient/HostedWorkflowResilient.csproj b/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Workflow-Resilient/HostedWorkflowResilient.csproj
index 79b8c35d5bf..035789a4e1b 100644
--- a/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Workflow-Resilient/HostedWorkflowResilient.csproj
+++ b/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Workflow-Resilient/HostedWorkflowResilient.csproj
@@ -30,8 +30,7 @@
-
-
+